Keep the tdb code in sync with Samba4.
authorJeremy Allison <jra@samba.org>
Wed, 7 Nov 2007 06:57:35 +0000 (22:57 -0800)
committerJeremy Allison <jra@samba.org>
Wed, 7 Nov 2007 06:57:35 +0000 (22:57 -0800)
Mainly this is the svn changes :

------------------------------------------------------------------------
r23238 | tridge | 2007-05-30 01:15:49 -0700 (Wed, 30 May 2007) | 6 lines

merged transaction lock changes from ctdb

this ensures that having the global lock also implies the transaction
lock

------------------------------------------------------------------------
r22832 | tridge | 2007-05-13 18:00:06 -0700 (Sun, 13 May 2007) | 3 lines

merged the latest tdb changes from ctdb to Samba4

Jeremy.
(This used to be commit ab11c0055761e97ba32a8c3ec4fa6f8763a262cd)

12 files changed:
source3/lib/tdb/Makefile.in
source3/lib/tdb/common/lock.c
source3/lib/tdb/common/tdb.c
source3/lib/tdb/common/tdb_private.h
source3/lib/tdb/common/transaction.c
source3/lib/tdb/common/traverse.c
source3/lib/tdb/configure.ac
source3/lib/tdb/include/tdb.h
source3/lib/tdb/libtdb.m4
source3/lib/tdb/tdb.pc.in
source3/lib/tdb/tools/tdbtest.c
source3/lib/tdb/tools/tdbtorture.c

index b2f42ea70fb16049e02b3b261932f9c283c8af1a..e1ecbb30ec880fb71f64dad7f2b86f8d18dbf10f 100644 (file)
@@ -12,10 +12,15 @@ libdir = @libdir@
 VPATH = @srcdir@:@libreplacedir@
 srcdir = @srcdir@
 builddir = @builddir@
-CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -I@libreplacedir@
+CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude 
 CFLAGS = $(CPPFLAGS) @CFLAGS@
 LDFLAGS = @LDFLAGS@
 EXEEXT = @EXEEXT@
+SHLD_FLAGS = @SHLD_FLAGS@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PICFLAG = @PICFLAG@
+SONAMEFLAG = @SONAMEFLAG@
+SHLIBEXT = @SHLIBEXT@
 
 .PHONY: test
 
@@ -23,11 +28,14 @@ PROGS = bin/tdbtool$(EXEEXT) bin/tdbdump$(EXEEXT) bin/tdbbackup$(EXEEXT)
 PROGS_NOINSTALL = bin/tdbtest$(EXEEXT) bin/tdbtorture$(EXEEXT)
 ALL_PROGS = $(PROGS) $(PROGS_NOINSTALL)
 
-TDB_OBJ = @TDBOBJ@ @LIBREPLACEOBJ@
+TDB_OBJ = @TDB_OBJ@ @LIBREPLACEOBJ@
 
 DIRS = bin common tools
 
-all: showflags dirs $(PROGS)
+SONAME = libtdb.$(SHLIBEXT).1
+SOLIB = libtdb.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+all: showflags dirs $(PROGS) $(SOLIB) libtdb.a
 
 showflags:
        @echo 'tdb will be compiled with flags:'
@@ -36,39 +44,53 @@ showflags:
        @echo '  LDFLAGS = $(LDFLAGS)'
        @echo '  LIBS = $(LIBS)'
 
+.SUFFIXES: .c .o
+
 .c.o:
        @echo Compiling $*.c
        @mkdir -p `dirname $@`
-       @$(CC) $(CFLAGS) -c $< -o $@
+       @$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@
 
 dirs:
        @mkdir -p $(DIRS)
 
 install: all
-       mkdir -p $(bindir)
-       mkdir -p $(includedir)
-       mkdir -p $(libdir) 
-       mkdir -p $(libdir)/pkgconfig
-       cp $(PROGS) $(bindir)
-       cp $(srcdir)/include/tdb.h $(includedir)
-       cp tdb.pc $(libdir)/pkgconfig
+       mkdir -p $(DESTDIR)$(bindir)
+       mkdir -p $(DESTDIR)$(includedir)
+       mkdir -p $(DESTDIR)$(libdir) 
+       mkdir -p $(DESTDIR)$(libdir)/pkgconfig
+       cp $(PROGS) $(DESTDIR)$(bindir)
+       cp $(srcdir)/include/tdb.h $(DESTDIR)$(includedir)
+       cp tdb.pc $(DESTDIR)$(libdir)/pkgconfig
+       cp libtdb.a $(SOLIB) $(DESTDIR)$(libdir)
 
 libtdb.a: $(TDB_OBJ)
        ar -rv libtdb.a $(TDB_OBJ)
 
-bin/tdbtest$(EXEEXT): tools/tdbtest.o libtdb.a
+libtdb.(SHLIBEXT): $(SOLIB)
+       ln -s $< $@
+
+$(SONAME): $(SOLIB)
+       ln -s $< $@
+
+$(SOLIB): $(TDB_OBJ)
+       $(CC) $(SHLD_FLAGS) $(SONAMEFLAG)$(SONAME) -o $@ $^
+
+TDB_LIB = libtdb.a
+
+bin/tdbtest$(EXEEXT): tools/tdbtest.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtest tools/tdbtest.o -L. -ltdb -lgdbm
 
-bin/tdbtool$(EXEEXT): tools/tdbtool.o libtdb.a
+bin/tdbtool$(EXEEXT): tools/tdbtool.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtool tools/tdbtool.o -L. -ltdb
 
-bin/tdbtorture$(EXEEXT): tools/tdbtorture.o libtdb.a
+bin/tdbtorture$(EXEEXT): tools/tdbtorture.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtorture tools/tdbtorture.o -L. -ltdb
 
-bin/tdbdump$(EXEEXT): tools/tdbdump.o libtdb.a
+bin/tdbdump$(EXEEXT): tools/tdbdump.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbdump tools/tdbdump.o -L. -ltdb
 
-bin/tdbbackup$(EXEEXT): tools/tdbbackup.o libtdb.a
+bin/tdbbackup$(EXEEXT): tools/tdbbackup.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbbackup tools/tdbbackup.o -L. -ltdb
 
 test: bin/tdbtorture$(EXEEXT)
@@ -79,6 +101,7 @@ installcheck: test install
 clean:
        rm -f $(ALL_PROGS) *.o *.a common/*.o tools/*.o tdb.pc
        rm -f test.db test.tdb torture.tdb test.gdbm
+       rm -f $(SONAME) $(SOLIB) libtdb.a
 
 distclean: clean
        rm -f *~ */*~
index 43be5d20e1eb9a92cc5dd3d0df14437927e47800..e3fe888c465f357adb436b7230d8e3070f073a63 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "tdb_private.h"
 
+#define TDB_MARK_LOCK 0x80000000
+
 void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
 {
        tdb->interrupt_sig_ptr = ptr;
@@ -116,10 +118,13 @@ int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len)
 
 
 /* lock a list in the database. list -1 is the alloc list */
-int tdb_lock(struct tdb_context *tdb, int list, int ltype)
+static int _tdb_lock(struct tdb_context *tdb, int list, int ltype, int op)
 {
        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 && 
@@ -169,10 +174,9 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype)
 
        /* 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,F_SETLKW,
+       if (!mark_lock &&
+           tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list, ltype, op,
                                     0, 1)) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d "
-                        "ltype=%d (%s)\n",  list, ltype, strerror(errno)));
                return -1;
        }
 
@@ -186,6 +190,25 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype)
        return 0;
 }
 
+/* lock a list in the database. list -1 is the alloc list */
+int tdb_lock(struct tdb_context *tdb, int list, int ltype)
+{
+       int ret;
+       ret = _tdb_lock(tdb, list, ltype, F_SETLKW);
+       if (ret) {
+               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d "
+                        "ltype=%d (%s)\n",  list, ltype, strerror(errno)));
+       }
+       return ret;
+}
+
+/* lock a list in the database. list -1 is the alloc list. non-blocking lock */
+int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype)
+{
+       return _tdb_lock(tdb, list, ltype, F_SETLK);
+}
+
+
 /* unlock the database: returns void because it's too late for errors. */
        /* changed to return int it may be interesting to know there
           has been an error  --simo */
@@ -194,6 +217,9 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
        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 && 
@@ -238,8 +264,12 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
         * 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--;
 
        /*
@@ -266,11 +296,50 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
        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 */
-static int _tdb_lockall(struct tdb_context *tdb, int ltype)
+static int _tdb_lockall(struct tdb_context *tdb, int ltype, int op)
 {
+       bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
+
+       ltype &= ~TDB_MARK_LOCK;
+
        /* There are no locks on read-only dbs */
        if (tdb->read_only || tdb->traverse_read)
                return TDB_ERRCODE(TDB_ERR_LOCK, -1);
@@ -290,9 +359,12 @@ static int _tdb_lockall(struct tdb_context *tdb, int ltype)
                return TDB_ERRCODE(TDB_ERR_LOCK, -1);
        }
 
-       if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, F_SETLKW, 
+       if (!mark_lock &&
+           tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, op,
                                     0, 4*tdb->header.hash_size)) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno)));
+               if (op == F_SETLKW) {
+                       TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno)));
+               }
                return -1;
        }
 
@@ -302,9 +374,15 @@ static int _tdb_lockall(struct tdb_context *tdb, int ltype)
        return 0;
 }
 
+
+
 /* unlock entire db */
 static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
 {
+       bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
+
+       ltype &= ~TDB_MARK_LOCK;
+
        /* There are no locks on read-only dbs */
        if (tdb->read_only || tdb->traverse_read) {
                return TDB_ERRCODE(TDB_ERR_LOCK, -1);
@@ -319,7 +397,8 @@ static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
                return 0;
        }
 
-       if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 
+       if (!mark_lock &&
+           tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 
                                     0, 4*tdb->header.hash_size)) {
                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno)));
                return -1;
@@ -334,7 +413,25 @@ static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
 /* lock entire database with write lock */
 int tdb_lockall(struct tdb_context *tdb)
 {
-       return _tdb_lockall(tdb, F_WRLCK);
+       return _tdb_lockall(tdb, F_WRLCK, F_SETLKW);
+}
+
+/* lock entire database with write lock - mark only */
+int tdb_lockall_mark(struct tdb_context *tdb)
+{
+       return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW);
+}
+
+/* unlock entire database with write lock - unmark only */
+int tdb_lockall_unmark(struct tdb_context *tdb)
+{
+       return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK);
+}
+
+/* lock entire database with write lock - nonblocking varient */
+int tdb_lockall_nonblock(struct tdb_context *tdb)
+{
+       return _tdb_lockall(tdb, F_WRLCK, F_SETLK);
 }
 
 /* unlock entire database with write lock */
@@ -346,7 +443,13 @@ int tdb_unlockall(struct tdb_context *tdb)
 /* lock entire database with read lock */
 int tdb_lockall_read(struct tdb_context *tdb)
 {
-       return _tdb_lockall(tdb, F_RDLCK);
+       return _tdb_lockall(tdb, F_RDLCK, F_SETLKW);
+}
+
+/* lock entire database with read lock - nonblock varient */
+int tdb_lockall_read_nonblock(struct tdb_context *tdb)
+{
+       return _tdb_lockall(tdb, F_RDLCK, F_SETLK);
 }
 
 /* unlock entire database with read lock */
@@ -362,6 +465,26 @@ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key)
        return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
 }
 
+/* lock/unlock one hash chain, non-blocking. This is meant to be used
+   to reduce contention - it cannot guarantee how many records will be
+   locked */
+int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key)
+{
+       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);
index 8f3c146843be3311e1890c0830bdd83f4ff9b841..0e9d1dbd7412942634d982c92fe3bef57d7bf572 100644 (file)
 TDB_DATA tdb_null;
 
 /*
-  increment the tdb sequence number if the tdb has been opened using
+  non-blocking increment of the tdb sequence number if the tdb has been opened using
   the TDB_SEQNUM flag
 */
-static void tdb_increment_seqnum(struct tdb_context *tdb)
+void tdb_increment_seqnum_nonblock(struct tdb_context *tdb)
 {
        tdb_off_t seqnum=0;
        
@@ -41,16 +41,29 @@ static void tdb_increment_seqnum(struct tdb_context *tdb)
                return;
        }
 
-       if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) {
-               return;
-       }
-
        /* we ignore errors from this, as we have no sane way of
           dealing with them.
        */
        tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
        seqnum++;
        tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum);
+}
+
+/*
+  increment the tdb sequence number if the tdb has been opened using
+  the TDB_SEQNUM flag
+*/
+static void tdb_increment_seqnum(struct tdb_context *tdb)
+{
+       if (!(tdb->flags & TDB_SEQNUM)) {
+               return;
+       }
+
+       if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) {
+               return;
+       }
+
+       tdb_increment_seqnum_nonblock(tdb);
 
        tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1);
 }
@@ -653,3 +666,11 @@ int tdb_get_flags(struct tdb_context *tdb)
        return tdb->flags;
 }
 
+
+/*
+  enable sequence number handling on an open tdb
+*/
+void tdb_enable_seqnum(struct tdb_context *tdb)
+{
+       tdb->flags |= TDB_SEQNUM;
+}
index daef07aff1cbc2463f82810979aaf03b667035c1..00bd0eb537a61f3639e577bd55bb2d8465c2876b 100644 (file)
@@ -162,6 +162,7 @@ struct tdb_context {
        struct tdb_transaction *transaction;
        int page_size;
        int max_dead_records;
+       bool have_transaction_lock;
        volatile sig_atomic_t *interrupt_sig_ptr;
 };
 
@@ -174,6 +175,8 @@ void tdb_mmap(struct tdb_context *tdb);
 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);
index 8263bd7f388b6f12410a6d600c2583a7efc73eeb..7eaacf7a164fbad3052c8b211ca8f547af3ba3be 100644 (file)
@@ -422,9 +422,7 @@ 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_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;
        }
@@ -468,6 +466,7 @@ int tdb_transaction_start(struct tdb_context *tdb)
                              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;
        }
 
@@ -475,7 +474,7 @@ int tdb_transaction_start(struct tdb_context *tdb)
        
 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;
@@ -530,7 +529,7 @@ int tdb_transaction_cancel(struct tdb_context *tdb)
        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);
        
index 86fa4fd48e605a064f525f046aa7886145437600..6fc576a55a324b942973356cc371a352a1cb88fb 100644 (file)
@@ -204,12 +204,10 @@ int tdb_traverse_read(struct tdb_context *tdb,
 {
        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;
        }
 
@@ -217,7 +215,7 @@ int tdb_traverse_read(struct tdb_context *tdb,
        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;
 }
@@ -236,15 +234,13 @@ int tdb_traverse(struct tdb_context *tdb,
                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;
 }
index 8bfff589cc58e1d81dedeab9b9e60ff4b6eb5ee6..de8fc9c2b593b336111a37f0977c997b58379714 100644 (file)
@@ -6,5 +6,9 @@ AC_INIT(tdb, 1.1.0)
 AC_CONFIG_SRCDIR([common/tdb.c])
 AC_CONFIG_HEADER(include/config.h)
 AC_LIBREPLACE_ALL_CHECKS
+AC_LD_SONAMEFLAG
+AC_LD_PICFLAG
+AC_LD_SHLDFLAGS
+AC_LD_SHLIBEXT
 m4_include(libtdb.m4)
 AC_OUTPUT(Makefile tdb.pc)
index 21410e840bbc893d1970468c39c4267338d7bc49..7de4c419a81ea0c67b6faadfc22b0208c44a0c6b 100644 (file)
@@ -116,9 +116,13 @@ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *);
 int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *);
 int tdb_exists(struct tdb_context *tdb, TDB_DATA key);
 int tdb_lockall(struct tdb_context *tdb);
+int tdb_lockall_nonblock(struct tdb_context *tdb);
 int tdb_unlockall(struct tdb_context *tdb);
 int tdb_lockall_read(struct tdb_context *tdb);
+int tdb_lockall_read_nonblock(struct tdb_context *tdb);
 int tdb_unlockall_read(struct tdb_context *tdb);
+int tdb_lockall_mark(struct tdb_context *tdb);
+int tdb_lockall_unmark(struct tdb_context *tdb);
 const char *tdb_name(struct tdb_context *tdb);
 int tdb_fd(struct tdb_context *tdb);
 tdb_log_func tdb_log_fn(struct tdb_context *tdb);
@@ -131,12 +135,17 @@ int tdb_get_seqnum(struct tdb_context *tdb);
 int tdb_hash_size(struct tdb_context *tdb);
 size_t tdb_map_size(struct tdb_context *tdb);
 int tdb_get_flags(struct tdb_context *tdb);
+void tdb_enable_seqnum(struct tdb_context *tdb);
+void tdb_increment_seqnum_nonblock(struct tdb_context *tdb);
 
 /* Low level locking functions: use with care */
 int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key);
+int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key);
 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);
 
 void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr);
 
index fefa5912c265858e373cdc5ed70ae942e7b5991d..7682edada9312d9c6c204ba56dc2db005de78d3d 100644 (file)
@@ -12,11 +12,17 @@ done
 if test x"$tdbdir" = "x"; then
    AC_MSG_ERROR([cannot find tdb source in $tdbpaths])
 fi
-TDBOBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o"
-TDBOBJ="$TDBOBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o"
-AC_SUBST(TDBOBJ)
+TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o"
+TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o"
+AC_SUBST(TDB_OBJ)
 AC_SUBST(LIBREPLACEOBJ)
 
+TDB_LIBS=""
+AC_SUBST(TDB_LIBS)
+
+TDB_CFLAGS="-I$tdbdir/include"
+AC_SUBST(TDB_CFLAGS)
+
 AC_CHECK_FUNCS(mmap pread pwrite getpagesize utime)
 AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h)
 
index 8180d4718502df8825ff3f2db8a7d43422dc3322..bb440f9cf55ee2df2893738331a08302d8340378 100644 (file)
@@ -5,6 +5,6 @@ includedir=@includedir@
 
 Name: tdb
 Description: A trivial database
-Version: 4.0
+Version: @PACKAGE_VERSION@
 Libs: -L${libdir} -ltdb
 Cflags: -I${includedir} 
index 1564a42bc41c56977730acfc7c539f37349b1bf2..416bc50a5b073c07fad11c2d10a7a08fdb9253ae 100644 (file)
@@ -214,7 +214,7 @@ static void merge_test(void)
        key.dptr = keys[3];
        tdb_delete(db, key);
 }
-       
+
  int main(int argc, const char *argv[])
 {
        int i, seed=0;
index 14a2b48cdc78d4bf5e4d215b1f2cd354e08312cc..ca71c736ad425a8cebe2264b35826a14443d679f 100644 (file)
@@ -238,7 +238,7 @@ static void usage(void)
 
        unlink("torture.tdb");
 
-       pids = calloc(sizeof(pid_t), num_procs);
+       pids = (pid_t *)calloc(sizeof(pid_t), num_procs);
        pids[0] = getpid();
 
        for (i=0;i<num_procs-1;i++) {