summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2011-05-10 09:08:21 -0400
committerAndreas Schneider <asn@samba.org>2011-08-10 18:14:04 +0200
commitb58d446c03f55203486fe7bb14f08b428efec6f3 (patch)
tree1a7bb12d3bf72d4c277a6ff2e072dcd80acd1c1a
parentf6ae58f24256a339eec3b17699b10ab11482e6c1 (diff)
downloadsamba-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.c18
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;