s3-prefork: better timing out semantics
authorSimo Sorce <idra@samba.org>
Tue, 10 May 2011 13:08:21 +0000 (09:08 -0400)
committerAndreas Schneider <asn@samba.org>
Wed, 10 Aug 2011 16:14:04 +0000 (18:14 +0200)
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>
source3/lib/server_prefork.c

index 53b6d5c9929db39f9b33f9eb661a98a77a5fd68c..211a54b95b30322e96923ec19db8f3892f9f1b2d 100644 (file)
@@ -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;