tdb: Add a non-blocking version of tdb_transaction_start
authorVolker Lendecke <vl@samba.org>
Fri, 26 Mar 2010 12:30:28 +0000 (13:30 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 26 Mar 2010 17:19:20 +0000 (18:19 +0100)
lib/tdb/common/lock.c
lib/tdb/common/tdb_private.h
lib/tdb/common/transaction.c
lib/tdb/common/traverse.c
lib/tdb/include/tdb.h

index f156c0fa7b2e548640d47db23df71c9427ec73ce..16c93f3375a5430ab12bb3d0e245be0d4860e7bc 100644 (file)
@@ -299,13 +299,17 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
 /*
   get the transaction lock
  */
-int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype, bool block)
 {
        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) {
+                                    block ? F_SETLKW : F_SETLK,
+                                    0, 1) == -1) {
+               if (!block && (errno == EAGAIN)) {
+                       return -1;
+               }
                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
                tdb->ecode = TDB_ERR_LOCK;
                return -1;
index ffac89ff0e315195b3defdebc35184ef7ab6a038..562b813ff115c4002a16c771ca6ed1172322b074 100644 (file)
@@ -180,7 +180,7 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype);
 int tdb_lock_nonblock(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_lock(struct tdb_context *tdb, int ltype, bool block);
 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);
index 7acda640c8d32338de6e8651971d5f848740aae6..d542a3f69ffcd183dd50b59b3ffe2ba297fb3e60 100644 (file)
@@ -398,7 +398,7 @@ static const struct tdb_methods transaction_methods = {
   start a tdb transaction. No token is returned, as only a single
   transaction is allowed to be pending per tdb_context
 */
-int tdb_transaction_start(struct tdb_context *tdb)
+static int _tdb_transaction_start(struct tdb_context *tdb, bool block)
 {
        /* some sanity checks */
        if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) {
@@ -446,9 +446,12 @@ int tdb_transaction_start(struct tdb_context *tdb)
        /* 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_transaction_lock(tdb, F_WRLCK) == -1) {
+       if (tdb_transaction_lock(tdb, F_WRLCK, block) == -1) {
                SAFE_FREE(tdb->transaction->blocks);
                SAFE_FREE(tdb->transaction);
+               if (!block) {
+                       tdb->ecode = TDB_ERR_NOLOCK;
+               }
                return -1;
        }
        
@@ -496,6 +499,15 @@ fail:
        return -1;
 }
 
+int tdb_transaction_start(struct tdb_context *tdb)
+{
+       return _tdb_transaction_start(tdb, true);
+}
+
+int tdb_transaction_start_nonblock(struct tdb_context *tdb)
+{
+       return _tdb_transaction_start(tdb, false);
+}
 
 /*
   cancel the current transaction
index 69c81e6e98fd27b7a4d8d86c7c6f620e64cd552a..9e91c83b2e618bfbfa171a53c41fd3d9dc445662 100644 (file)
@@ -209,7 +209,7 @@ int tdb_traverse_read(struct tdb_context *tdb,
        /* we need to get a read lock on the transaction lock here to
           cope with the lock ordering semantics of solaris10 */
        if (!in_transaction) {
-               if (tdb_transaction_lock(tdb, F_RDLCK)) {
+               if (tdb_transaction_lock(tdb, F_RDLCK, true)) {
                        return -1;
                }
        }
@@ -244,7 +244,7 @@ int tdb_traverse(struct tdb_context *tdb,
        }
        
        if (!in_transaction) {
-               if (tdb_transaction_lock(tdb, F_WRLCK)) {
+               if (tdb_transaction_lock(tdb, F_WRLCK, true)) {
                        return -1;
                }
        }
index 94b5e366b90cd28002ca4c21e405a0f2197b5ffb..3d76ffd444ec196ca14730179c446610f64e5165 100644 (file)
@@ -129,6 +129,7 @@ int tdb_fd(struct tdb_context *tdb);
 tdb_log_func tdb_log_fn(struct tdb_context *tdb);
 void *tdb_get_logging_private(struct tdb_context *tdb);
 int tdb_transaction_start(struct tdb_context *tdb);
+int tdb_transaction_start_nonblock(struct tdb_context *tdb);
 int tdb_transaction_commit(struct tdb_context *tdb);
 int tdb_transaction_cancel(struct tdb_context *tdb);
 int tdb_transaction_recover(struct tdb_context *tdb);