From 3665777a5bc7ffa92f64ba17daf4cc66c3607198 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Oct 2002 22:53:18 +0000 Subject: 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) --- source3/tdb/tdb.c | 4 ++++ source3/tdb/tdb.h | 2 +- source3/tdb/tdbutil.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 49 insertions(+), 6 deletions(-) (limited to 'source3/tdb') 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)) { -- cgit