------------------------------------------------------------ revno: 256 revision-id: [EMAIL PROTECTED] parent: [EMAIL PROTECTED] committer: Andrew Tridgell <[EMAIL PROTECTED]> branch nick: tridge timestamp: Sat 2007-05-05 17:14:33 +1000 message: added tdb_chainlock_mark() call, which can be used to mark a chain locked without actually locking it. This will be used to guarantee forward progress in the ctdb non-blocking lockwait code modified: lib/tdb/common/lock.c lock.c-20070220022425-m1wibgjq7n5hahs6-7 lib/tdb/include/tdb.h tdb.h-20070125040949-7t3f5zdl1q4z9hyv-101 === modified file 'lib/tdb/common/lock.c' --- a/lib/tdb/common/lock.c 2007-04-16 13:03:36 +0000 +++ b/lib/tdb/common/lock.c 2007-05-05 07:14:33 +0000 @@ -28,6 +28,8 @@ #include "tdb_private.h" +#define TDB_MARK_LOCK 0x80000000 + /* a byte range locking function - return 0 on success this functions locks/unlocks 1 byte at the specified offset. @@ -109,6 +111,9 @@ { struct tdb_lock_type *new_lck; int i; + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; /* a global lock allows us to avoid per chain locks */ if (tdb->global_lock.count && @@ -158,7 +163,8 @@ /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ - if (tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list,ltype, op, + if (!mark_lock && + tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list, ltype, op, 0, 1)) { return -1; } @@ -200,6 +206,9 @@ int ret = -1; int i; struct tdb_lock_type *lck = NULL; + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; /* a global lock allows us to avoid per chain locks */ if (tdb->global_lock.count && @@ -244,8 +253,12 @@ * anyway. */ - ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, - F_SETLKW, 0, 1); + if (mark_lock) { + ret = 0; + } else { + ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, + F_SETLKW, 0, 1); + } tdb->num_locks--; /* @@ -376,6 +389,18 @@ return tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } +/* mark a chain as locked without actually locking it. Warning! use with great caution! */ +int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); +} + +/* unmark a chain as locked without actually locking it. Warning! use with great caution! */ +int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); +} + int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) { return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
=== modified file 'lib/tdb/include/tdb.h' --- a/lib/tdb/include/tdb.h 2007-05-04 12:18:00 +0000 +++ b/lib/tdb/include/tdb.h 2007-05-05 07:14:33 +0000 @@ -140,6 +140,8 @@ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key); int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key); int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key); /* Debug functions. Not used in production. */ void tdb_dump_all(struct tdb_context *tdb);