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
      /* 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.
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