summaryrefslogtreecommitdiffstats
path: root/source3/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-09-14 11:15:34 +0200
committerVolker Lendecke <vl@samba.org>2014-09-18 20:36:11 +0200
commit5454f71fc05c551c2465c2d10ee5e0971058bf02 (patch)
treea1171f6e9c1d6c3a1c76edb05d552777f90c83ce /source3/lib
parent3ffff13e0d66ac6f871c3d87d15c5c3c8095ed33 (diff)
downloadsamba-5454f71fc05c551c2465c2d10ee5e0971058bf02.tar.gz
samba-5454f71fc05c551c2465c2d10ee5e0971058bf02.tar.xz
samba-5454f71fc05c551c2465c2d10ee5e0971058bf02.zip
lib: Move tdb lock timeout fns to source3
This is not the nicest code and needs to be replaced. Remove it from common. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Martin Schwenke <martin@meltin.net>
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/util_tdb.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index 440c28b98d..38c5fa0acd 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -451,3 +451,81 @@ done:
talloc_free(ost);
return ret;
}
+
+static sig_atomic_t gotalarm;
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig(int signum)
+{
+ gotalarm = 1;
+}
+
+/****************************************************************************
+ Lock a chain with timeout (in seconds).
+****************************************************************************/
+
+static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type)
+{
+ /* Allow tdb_chainlock to be interrupted by an alarm. */
+ int ret;
+ gotalarm = 0;
+
+ if (timeout) {
+ CatchSignal(SIGALRM, gotalarm_sig);
+ tdb_setalarm_sigptr(tdb, &gotalarm);
+ alarm(timeout);
+ }
+
+ if (rw_type == F_RDLCK)
+ ret = tdb_chainlock_read(tdb, key);
+ else
+ ret = tdb_chainlock(tdb, key);
+
+ if (timeout) {
+ alarm(0);
+ tdb_setalarm_sigptr(tdb, NULL);
+ CatchSignal(SIGALRM, SIG_IGN);
+ if (gotalarm && (ret != 0)) {
+ DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
+ timeout, key.dptr, tdb_name(tdb)));
+ /* TODO: If we time out waiting for a lock, it might
+ * be nice to use F_GETLK to get the pid of the
+ * process currently holding the lock and print that
+ * as part of the debugging message. -- mbp */
+ return -1;
+ }
+ }
+
+ return ret == 0 ? 0 : -1;
+}
+
+/****************************************************************************
+ Write lock a chain. Return non-zero if timeout or lock failed.
+****************************************************************************/
+
+int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
+{
+ return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK);
+}
+
+int tdb_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval,
+ int timeout)
+{
+ TDB_DATA key = string_term_tdb_data(keyval);
+
+ return tdb_chainlock_with_timeout(tdb, key, timeout);
+}
+
+/****************************************************************************
+ Read lock a chain by string. Return non-zero if timeout or lock failed.
+****************************************************************************/
+
+int tdb_read_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout)
+{
+ TDB_DATA key = string_term_tdb_data(keyval);
+
+ return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_RDLCK);
+}