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