diff options
author | Volker Lendecke <vl@samba.org> | 2012-08-10 17:00:38 +0200 |
---|---|---|
committer | Christian Ambach <ambi@samba.org> | 2012-08-16 19:44:00 +0200 |
commit | cbe25105c7fc51b178bf4df217812ccf48c472a1 (patch) | |
tree | 9cd3fca093501e81fdfb4a767b4d8dad05bdd323 | |
parent | b83cd05ce1ff3357428cbc789ac4dbd08aa706ec (diff) | |
download | samba-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
-rw-r--r-- | source3/lib/g_lock.c | 24 |
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; |