summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2012-08-10 17:00:38 +0200
committerChristian Ambach <ambi@samba.org>2012-08-16 19:44:00 +0200
commitcbe25105c7fc51b178bf4df217812ccf48c472a1 (patch)
tree9cd3fca093501e81fdfb4a767b4d8dad05bdd323 /source3/lib
parentb83cd05ce1ff3357428cbc789ac4dbd08aa706ec (diff)
downloadsamba-cbe25105c7fc51b178bf4df217812ccf48c472a1.tar.gz
samba-cbe25105c7fc51b178bf4df217812ccf48c472a1.tar.bz2
samba-cbe25105c7fc51b178bf4df217812ccf48c472a1.zip
s3-g_lock: Make g_lock_lock more robust
If for some reason the cleanup of dbwrap_watch_send does not work properly, we might starve indefinitely. Make the lock routine more robust by retrying every 5-10 seconds. g_lock_trylock will clean up orphaned entries. Signed-off-by: Christian Ambach <ambi@samba.org> Autobuild-User(master): Christian Ambach <ambi@samba.org> Autobuild-Date(master): Thu Aug 16 19:44:00 CEST 2012 on sn-devel-104
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/g_lock.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index f7fe3db731..4535b35569 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -227,6 +227,12 @@ struct tevent_req *g_lock_lock_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
+ if (!tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(5 + sys_random() % 5, 0))) {
+ tevent_req_oom(req);
+ return tevent_req_post(req, ev);
+ }
tevent_req_set_callback(subreq, g_lock_lock_retry, req);
return req;
}
@@ -243,6 +249,18 @@ static void g_lock_lock_retry(struct tevent_req *subreq)
status = dbwrap_record_watch_recv(subreq, talloc_tos(), &rec);
TALLOC_FREE(subreq);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
+ rec = dbwrap_fetch_locked(
+ state->ctx->db, talloc_tos(),
+ string_term_tdb_data(state->name));
+ if (rec == NULL) {
+ status = map_nt_error_from_unix(errno);
+ } else {
+ status = NT_STATUS_OK;
+ }
+ }
+
if (tevent_req_nterror(req, status)) {
return;
}
@@ -263,6 +281,12 @@ static void g_lock_lock_retry(struct tevent_req *subreq)
if (tevent_req_nomem(subreq, req)) {
return;
}
+ if (!tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(5 + sys_random() % 5, 0))) {
+ tevent_req_oom(req);
+ return;
+ }
tevent_req_set_callback(subreq, g_lock_lock_retry, req);
return;