------------------------------------------------------------
revno: 329
revision-id: [EMAIL PROTECTED]
parent: [EMAIL PROTECTED]
committer: Andrew Tridgell <[EMAIL PROTECTED]>
branch nick: tridge
timestamp: Tue 2007-05-22 13:14:51 +1000
message:
  global lock should imply the transaction lock
modified:
  lib/tdb/common/lock.c          lock.c-20070220022425-m1wibgjq7n5hahs6-7
  lib/tdb/common/tdb_private.h   
tdb_private.h-20070220022425-m1wibgjq7n5hahs6-10
  lib/tdb/common/transaction.c   
transaction.c-20070220022425-m1wibgjq7n5hahs6-11
  lib/tdb/common/traverse.c      traverse.c-20070220022425-m1wibgjq7n5hahs6-12
=== modified file 'lib/tdb/common/lock.c'
--- a/lib/tdb/common/lock.c     2007-05-12 04:33:10 +0000
+++ b/lib/tdb/common/lock.c     2007-05-22 03:14:51 +0000
@@ -285,6 +285,41 @@
        return ret;
 }
 
+/*
+  get the transaction lock
+ */
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
+{
+       if (tdb->have_transaction_lock || tdb->global_lock.count) {
+               return 0;
+       }
+       if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype, 
+                                    F_SETLKW, 0, 1) == -1) {
+               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to 
get transaction lock\n"));
+               tdb->ecode = TDB_ERR_LOCK;
+               return -1;
+       }
+       tdb->have_transaction_lock = 1;
+       return 0;
+}
+
+/*
+  release the transaction lock
+ */
+int tdb_transaction_unlock(struct tdb_context *tdb)
+{
+       int ret;
+       if (!tdb->have_transaction_lock) {
+               return 0;
+       }
+       ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, 
F_SETLKW, 0, 1);
+       if (ret == 0) {
+               tdb->have_transaction_lock = 0;
+       }
+       return ret;
+}
+
+
 
 
 /* lock/unlock entire database */

=== modified file 'lib/tdb/common/tdb_private.h'
--- a/lib/tdb/common/tdb_private.h      2007-04-21 08:09:37 +0000
+++ b/lib/tdb/common/tdb_private.h      2007-05-22 03:14:51 +0000
@@ -170,6 +170,7 @@
        struct tdb_transaction *transaction;
        int page_size;
        int max_dead_records;
+       bool have_transaction_lock;
 };
 
 
@@ -181,6 +182,8 @@
 int tdb_lock(struct tdb_context *tdb, int list, int ltype);
 int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
 int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int 
lck_type, int probe, size_t len);
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype);
+int tdb_transaction_unlock(struct tdb_context *tdb);
 int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len);
 int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off);
 int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off);

=== modified file 'lib/tdb/common/transaction.c'
--- a/lib/tdb/common/transaction.c      2007-04-16 12:52:58 +0000
+++ b/lib/tdb/common/transaction.c      2007-05-22 03:14:51 +0000
@@ -423,9 +423,7 @@
        /* get the transaction write lock. This is a blocking lock. As
           discussed with Volker, there are a number of ways we could
           make this async, which we will probably do in the future */
-       if (tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed 
to get transaction lock\n"));
-               tdb->ecode = TDB_ERR_LOCK;
+       if (tdb_transaction_lock(tdb, F_WRLCK) == -1) {
                SAFE_FREE(tdb->transaction);
                return -1;
        }
@@ -469,6 +467,7 @@
                              TDB_HASHTABLE_SIZE(tdb)) != 0) {
                TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed 
to prime hash table\n"));
                tdb->ecode = TDB_ERR_IO;
+               tdb->methods = tdb->transaction->io_methods;
                goto fail;
        }
 
@@ -476,7 +475,7 @@
        
 fail:
        tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
-       tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+       tdb_transaction_unlock(tdb);
        SAFE_FREE(tdb->transaction->hash_heads);
        SAFE_FREE(tdb->transaction);
        return -1;
@@ -531,7 +530,7 @@
        tdb->methods = tdb->transaction->io_methods;
 
        tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
-       tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+       tdb_transaction_unlock(tdb);
        SAFE_FREE(tdb->transaction->hash_heads);
        SAFE_FREE(tdb->transaction);
        

=== modified file 'lib/tdb/common/traverse.c'
--- a/lib/tdb/common/traverse.c 2007-02-20 02:24:45 +0000
+++ b/lib/tdb/common/traverse.c 2007-05-22 03:14:51 +0000
@@ -205,12 +205,10 @@
 {
        struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
        int ret;
-       
+
        /* we need to get a read lock on the transaction lock here to
           cope with the lock ordering semantics of solaris10 */
-       if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_RDLCK, F_SETLKW, 
0, 1) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse_read: failed to 
get transaction lock\n"));
-               tdb->ecode = TDB_ERR_LOCK;
+       if (tdb_transaction_lock(tdb, F_RDLCK)) {
                return -1;
        }
 
@@ -218,7 +216,7 @@
        ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
        tdb->traverse_read--;
 
-       tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 
1);
+       tdb_transaction_unlock(tdb);
 
        return ret;
 }
@@ -237,15 +235,13 @@
                return tdb_traverse_read(tdb, fn, private_data);
        }
        
-       if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 
0, 1) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse: failed to get 
transaction lock\n"));
-               tdb->ecode = TDB_ERR_LOCK;
+       if (tdb_transaction_lock(tdb, F_WRLCK)) {
                return -1;
        }
 
        ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
 
-       tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 
1);
+       tdb_transaction_unlock(tdb);
 
        return ret;
 }

Reply via email to