------------------------------------------------------------
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);

Reply via email to