Add chainlock_read functions to get a read lock. Used in *massively*
authorJeremy Allison <jra@samba.org>
Sat, 9 Nov 2002 03:36:47 +0000 (03:36 +0000)
committerJeremy Allison <jra@samba.org>
Sat, 9 Nov 2002 03:36:47 +0000 (03:36 +0000)
contended tdb's (and I've got one :-).
Jeremy.

source/tdb/tdb.c
source/tdb/tdbutil.c

index 2a6dca16a8e0ff1a5c5ebfed7cc0623116a1a460..e539376ac7947b6cbbcf191aab811d6ebbef40ef 100644 (file)
@@ -186,7 +186,7 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
 
        if (tdb->flags & TDB_NOLOCK)
                return 0;
-       if (tdb->read_only) {
+       if ((rw_type == F_WRLCK) && (tdb->read_only)) {
                errno = EACCES;
                return -1;
        }
@@ -1802,6 +1802,16 @@ int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key)
        return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK);
 }
 
+int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+       return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK);
+}
+
+int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+       return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK);
+}
+
 
 /* register a loging function */
 void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...))
index ad97f4504459164b7736d830eb420506b030983d..5498872f8abb8fd98cf504226ac8029bda0fd3e1 100644 (file)
@@ -39,7 +39,7 @@ static void gotalarm_sig(void)
  Lock a chain with timeout (in seconds).
 ****************************************************************************/
 
-int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
+static int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type)
 {
        /* Allow tdb_chainlock to be interrupted by an alarm. */
        int ret;
@@ -51,13 +51,19 @@ int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int tim
                alarm(timeout);
        }
 
-       ret = tdb_chainlock(tdb, key);
+       if (rw_type == F_RDLCK)
+               ret = tdb_chainlock_read(tdb, key);
+       else
+               ret = tdb_chainlock(tdb, key);
 
        if (timeout) {
                alarm(0);
                CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
-               if (gotalarm)
+               if (gotalarm) {
+                       DEBUG(0,("tdb_chainlock_with_timeout: alarm (%u) timed out for key %s in tdb %s\n",
+                               timeout, key.dptr, tdb->name ));
                        return -1;
+               }
        }
 
        return ret;
@@ -74,7 +80,7 @@ int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval, unsigned int timeout)
        key.dptr = keyval;
        key.dsize = strlen(keyval)+1;
        
-       return tdb_chainlock_with_timeout(tdb, key, timeout);
+       return tdb_chainlock_with_timeout(tdb, key, timeout, F_WRLCK);
 }
 
 /****************************************************************************
@@ -91,6 +97,35 @@ void tdb_unlock_bystring(TDB_CONTEXT *tdb, char *keyval)
        tdb_chainunlock(tdb, key);
 }
 
+/****************************************************************************
+ Read lock a chain by string. Return -1 if timeout or lock failed.
+****************************************************************************/
+
+int tdb_read_lock_bystring(TDB_CONTEXT *tdb, char *keyval, unsigned int timeout)
+{
+       TDB_DATA key;
+
+       key.dptr = keyval;
+       key.dsize = strlen(keyval)+1;
+       
+       return tdb_chainlock_with_timeout(tdb, key, timeout, F_RDLCK);
+}
+
+/****************************************************************************
+ Read unlock a chain by string.
+****************************************************************************/
+
+void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, char *keyval)
+{
+       TDB_DATA key;
+
+       key.dptr = keyval;
+       key.dsize = strlen(keyval)+1;
+       
+       tdb_chainunlock_read(tdb, key);
+}
+
+
 /****************************************************************************
  Fetch a int32 value by a arbitrary blob key, return -1 if not found.
  Output is int32 in native byte order.