FCNTL on Solaris
David Collier-Brown
davecb at canada.sun.com
Mon Apr 22 11:13:26 GMT 2002
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 | davecb at canada.sun.com
More information about the samba-technical
mailing list