Rev 256: 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 in http://samba.org/~tridge/ctdb

tridge at samba.org tridge at samba.org
Sat May 5 07:14:34 GMT 2007


------------------------------------------------------------
revno: 256
revision-id: tridge at samba.org-20070505071433-i3i06lprinozpxhe
parent: tridge at samba.org-20070505040946-iji1cxsyb8ail7bk
committer: Andrew Tridgell <tridge at samba.org>
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);



More information about the samba-cvs mailing list