From 251aaafe3a9213118ac3a92def9ab2104c40d12a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Sep 2005 01:26:34 +0000 Subject: r10522: finally got the locking working on solaris10. This adds a read lock on 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 | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/lib') diff --git a/source4/lib/tdb/common/traverse.c b/source4/lib/tdb/common/traverse.c index 9271b75aa8..00fe5be923 100644 --- a/source4/lib/tdb/common/traverse.c +++ b/source4/lib/tdb/common/traverse.c @@ -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; } -- cgit