Jeremy Allison wrote:
> Errrr. I don't understand this email. What "case 3"
> are you talking about here ?

        Sorry, not enough coffie (;-))

        I actually was referring to case three in the
        development of a lock-free check, which I had
        just whiteboarded and found **horrible**.  
        Pretend I didn't even suggest it!

> >         I haven't looked at the code, but if it uses F_SETLKW
> >         you might want to do a trylock first, implemented via
> >         F_GETLK or F_SETLK, as this would allow subsequent
> >         processes to continue, knowing that someone's fixing
> >         the tdb, and that they can access it later using the
> >         normal locking regime.

        In tdb/tdb.c, at line 1459 in tdb_open_ex, the code
        says 
      /* ensure there is only one process initialising at once */
       if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) {
                TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global
lock on %s: %s\n",
                         name, strerror(errno)));
                goto fail;      /* errno set by tdb_brlock */

        This is an example of safe serialization code, the kind
        of thing that may be in use in this particular case
        (I'm don't think this is the one: it just looks similar)

        I'm of the opinion that the right code for this type
        of test (not necessarily this exact one!)  would be a 
        tdb_trylock(), which does an fcntl(tdb->fd,F_SETLK, &fl)
        the way tdb_brlock does, but then checks the lock type 
        which will be set to F_UNLCK if the lock is, at that moment,
        unlocked. If unlocked, it would try to take a lock,
        as quick as possible to keep the contention window small,
        and if not it would return "it's locked".

        If it returned "it's locked", then there would be no need
        to do the iteration, as someone else would have been
        in the data structure, and it wouldn't necessarily need
        cleaning up. This is the case that would allow you to
        complete in bounded time.


        If it returned "it was unlocked, here's the lock" you'd know
        it is ok to do the iteration to clean up, but not if 
        someone had just done it already for you. And you'd have to take
        a lock, and possibly block until another process finished,
        as there is a window of opportunity for two processes to
        wait for the lock.

        Not optimal, but provably bounded in most cases, bounded
        some large and fixed percentage of time in all other cases.
        A true fcntl trylock would be demonstrably optimal.
        
--dave
-- 
David Collier-Brown,           | Always do right. This will gratify 
Performance & Engineering      | some people and astonish the rest.
Americas Customer Engineering, |                      -- Mark Twain
(905) 415-2849                 | [EMAIL PROTECTED]

Reply via email to