r10522: finally got the locking working on solaris10. This adds a read lock on
authorAndrew Tridgell <tridge@samba.org>
Tue, 27 Sep 2005 01:26:34 +0000 (01:26 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:39:00 +0000 (13:39 -0500)
the transaction lock in tdb_traverse_read(). This prevents a pattern
of locks which triggers the deadlock detection code in solaris10. I
suspect solaris10 is trying to prevent lock starvation by granting
locks in the order they were requested, which makes it much easier to
produce deadlocks.
(This used to be commit 54203aacd138c30826d54c5d9b6cc8d6e9e270f8)

source4/lib/tdb/common/traverse.c

index 9271b75aa81512948d0b01f72e8a745b6c0662cd..00fe5be923b0db8eb2534507e9a02e043badaf15 100644 (file)
@@ -205,9 +205,21 @@ 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) {
+               TDB_LOG((tdb, 0, "tdb_traverse_read: failed to get transaction lock\n"));
+               tdb->ecode = TDB_ERR_LOCK;
+               return -1;
+       }
+
        tdb->traverse_read++;
        ret = tdb_traverse_internal(tdb, fn, private, &tl);
        tdb->traverse_read--;
+
+       tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0);
+
        return ret;
 }