diff options
author | Simo Sorce <idra@samba.org> | 2011-05-10 09:08:21 -0400 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2011-08-10 18:14:04 +0200 |
commit | b58d446c03f55203486fe7bb14f08b428efec6f3 (patch) | |
tree | 1a7bb12d3bf72d4c277a6ff2e072dcd80acd1c1a | |
parent | f6ae58f24256a339eec3b17699b10ab11482e6c1 (diff) | |
download | samba-b58d446c03f55203486fe7bb14f08b428efec6f3.tar.gz samba-b58d446c03f55203486fe7bb14f08b428efec6f3.tar.bz2 samba-b58d446c03f55203486fe7bb14f08b428efec6f3.zip |
s3-prefork: better timing out semantics
If this child has no clients, let the lock functions block for 1 second,
and then immediately reschedule the operation. This means we catch the lock
as soon as possible on a free child.
If, instead, we are already serving a client, we want to be non blocking,
so we timeout immediately on getting the lock, and then we sleep a 1/10th of
a second.
This means that a busy child will be slightly slower on picking up the lock,
but we won't block the existing client from communicating with us as we
immediately react to activity on the already opened file handler.
Signed-off-by: Andreas Schneider <asn@samba.org>
-rw-r--r-- | source3/lib/server_prefork.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c index 53b6d5c992..211a54b95b 100644 --- a/source3/lib/server_prefork.c +++ b/source3/lib/server_prefork.c @@ -578,17 +578,23 @@ static void prefork_lock_handler(struct tevent_context *ev, { struct tevent_req *req; struct pf_lock_state *state; + struct timeval tv; + int timeout = 0; int ret; req = talloc_get_type_abort(pvt, struct tevent_req); state = tevent_req_data(req, struct pf_lock_state); + if (state->pf->num_clients > 0) { + timeout = 1; + } + switch (state->flags & PF_ASYNC_ACTION_MASK) { case PF_ASYNC_LOCK_GRAB: - ret = prefork_grab_lock(state->pf, state->lock_fd, 0); + ret = prefork_grab_lock(state->pf, state->lock_fd, timeout); break; case PF_ASYNC_LOCK_RELEASE: - ret = prefork_release_lock(state->pf, state->lock_fd, 0); + ret = prefork_release_lock(state->pf, state->lock_fd, timeout); break; default: ret = EINVAL; @@ -601,8 +607,12 @@ static void prefork_lock_handler(struct tevent_context *ev, tevent_req_done(req); return; case -1: - te = tevent_add_timer(ev, state, - tevent_timeval_current_ofs(1, 0), + if (timeout) { + tv = tevent_timeval_zero(); + } else { + tv = tevent_timeval_current_ofs(0, 100000); + } + te = tevent_add_timer(ev, state, tv, prefork_lock_handler, req); tevent_req_nomem(te, req); return; |