From b58d446c03f55203486fe7bb14f08b428efec6f3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 10 May 2011 09:08:21 -0400 Subject: 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 --- source3/lib/server_prefork.c | 18 ++++++++++++++---- 1 file 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; -- cgit