summaryrefslogtreecommitdiff
path: root/source3/tdb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-10-04 22:53:18 +0000
committerJeremy Allison <jra@samba.org>2002-10-04 22:53:18 +0000
commit3665777a5bc7ffa92f64ba17daf4cc66c3607198 (patch)
tree125ab749ead948e0a453bbfb4901afb716150eb7 /source3/tdb
parentcc169cc66824b5a4e33fca8fbd6bd733b7282639 (diff)
downloadsamba-3665777a5bc7ffa92f64ba17daf4cc66c3607198.tar.gz
samba-3665777a5bc7ffa92f64ba17daf4cc66c3607198.tar.bz2
samba-3665777a5bc7ffa92f64ba17daf4cc66c3607198.zip
Add a timeout to tdb_lock_bystring(). Ensure we never have more than
MAX_PRINT_JOBS in a queue. Jeremy. (This used to be commit 9fe3c0b90d4bff2217e3cb5a34b4683ca314c06e)
Diffstat (limited to 'source3/tdb')
-rw-r--r--source3/tdb/tdb.c4
-rw-r--r--source3/tdb/tdb.h2
-rw-r--r--source3/tdb/tdbutil.c49
3 files changed, 49 insertions, 6 deletions
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index 4143ac7781..c57d23cb6f 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -208,6 +208,10 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n",
tdb->fd, offset, rw_type, lck_type));
}
+ /* Was it an alarm timeout ? */
+ if (errno == EINTR && palarm_fired && *palarm_fired)
+ return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1);
+ /* Otherwise - generic lock error. */
/* errno set by fcntl */
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
}
diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h
index 42b88aeb16..dda89d0355 100644
--- a/source3/tdb/tdb.h
+++ b/source3/tdb/tdb.h
@@ -44,7 +44,7 @@ extern "C" {
/* error codes */
enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
- TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK };
+ TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT };
#ifndef u32
#define u32 unsigned
diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c
index 1a3a8bb9a5..e7650033b8 100644
--- a/source3/tdb/tdbutil.c
+++ b/source3/tdb/tdbutil.c
@@ -24,18 +24,57 @@
/* these are little tdb utility functions that are meant to make
dealing with a tdb database a little less cumbersome in Samba */
+static SIG_ATOMIC_T gotalarm;
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig(void)
+{
+ gotalarm = 1;
+}
+
+/****************************************************************************
+ Lock a chain with timeout (in seconds).
+****************************************************************************/
+
+int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
+{
+ /* Allow tdb_chainlock to be interrupted by an alarm. */
+ int ret;
+ gotalarm = 0;
+ tdb_set_lock_alarm(&gotalarm);
+
+ if (timeout) {
+ CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ alarm(timeout);
+ }
+
+ ret = tdb_chainlock(tdb, key);
+
+ if (timeout) {
+ alarm(0);
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+ if (gotalarm)
+ return -1;
+ }
+
+ return ret;
+}
+
/****************************************************************************
- Lock a chain by string.
+ Lock a chain by string. Return -1 if timeout or lock failed.
****************************************************************************/
-int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval)
+int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval, unsigned int timeout)
{
TDB_DATA key;
key.dptr = keyval;
key.dsize = strlen(keyval)+1;
- return tdb_chainlock(tdb, key);
+ return tdb_chainlock_with_timeout(tdb, key, timeout);
}
/****************************************************************************
@@ -230,7 +269,7 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, char *keystr, int32 *oldval, int
int32 val;
int32 ret = -1;
- if (tdb_lock_bystring(tdb, keystr) == -1)
+ if (tdb_lock_bystring(tdb, keystr,0) == -1)
return -1;
if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
@@ -271,7 +310,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, char *keystr, uint32 *oldval, ui
uint32 val;
BOOL ret = False;
- if (tdb_lock_bystring(tdb, keystr) == -1)
+ if (tdb_lock_bystring(tdb, keystr,0) == -1)
return False;
if (!tdb_fetch_uint32(tdb, keystr, &val)) {