From e3736f826b434bcdff5493fc533c11eba9bedc61 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 16 Aug 2011 11:37:41 -0400 Subject: s3-prefork: Fix worker flags handling. We can't have a clear idea of wether the worker is IDLE or BUSY. The only things we can tell is if it is Alive, whether it is currently Accepting connections or wether it is Exiting soon. Remove PF_WORKER_IDLE, PF_WORKER_BUSY and replace their use with PF_WORKER_ALIVE. Also properly assign PF_WORKER_ACCEPTING so that users of the API can rely on the flag. Signed-off-by: Andreas Schneider Signed-off-by: Simo Sorce --- source3/lib/server_prefork.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'source3/lib/server_prefork.c') diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c index ee725e883b..7d675485a0 100644 --- a/source3/lib/server_prefork.c +++ b/source3/lib/server_prefork.c @@ -109,7 +109,7 @@ bool prefork_create_pool(TALLOC_CTX *mem_ctx, case 0: /* THE CHILD */ - pfp->pool[i].status = PF_WORKER_IDLE; + pfp->pool[i].status = PF_WORKER_ALIVE; ret = pfp->main_fn(ev_ctx, msg_ctx, &pfp->pool[i], i + 1, pfp->listen_fd_size, @@ -196,7 +196,7 @@ int prefork_add_children(struct tevent_context *ev_ctx, case 0: /* THE CHILD */ - pfp->pool[i].status = PF_WORKER_IDLE; + pfp->pool[i].status = PF_WORKER_ALIVE; ret = pfp->main_fn(ev_ctx, msg_ctx, &pfp->pool[i], i + 1, pfp->listen_fd_size, @@ -252,7 +252,8 @@ int prefork_retire_children(struct prefork_pool *pfp, for (i = 0; i < pfp->pool_size; i++) { oldest[i].num = i; - if (pfp->pool[i].status == PF_WORKER_IDLE) { + if (pfp->pool[i].status == PF_WORKER_ALIVE || + pfp->pool[i].status == PF_WORKER_ACCEPTING) { oldest[i].started = pfp->pool[i].started; } else { oldest[i].started = now; @@ -264,7 +265,8 @@ int prefork_retire_children(struct prefork_pool *pfp, prefork_sort_oldest); for (i = 0, j = 0; i < pfp->pool_size && j < num_children; i++) { - if (pfp->pool[i].status == PF_WORKER_IDLE && + if ((pfp->pool[i].status == PF_WORKER_ALIVE || + pfp->pool[i].status == PF_WORKER_ACCEPTING) && pfp->pool[i].started <= age_limit) { /* tell the child it's time to give up */ DEBUG(5, ("Retiring pid %d!\n", pfp->pool[i].pid)); @@ -519,6 +521,8 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, } } + pf->status = PF_WORKER_ACCEPTING; + return req; } @@ -539,6 +543,14 @@ static void prefork_listen_accept_handler(struct tevent_context *ev, req = ctx->req; state = tevent_req_data(ctx->req, struct pf_listen_state); + if (state->pf->cmds == PF_SRV_MSG_EXIT) { + /* We have been asked to exit, so drop here and the next + * child will pick it up */ + state->pf->status = PF_WORKER_EXITING; + state->error = EINTR; + goto done; + } + ZERO_STRUCT(addr); addrlen = sizeof(addr); sd = accept(ctx->listen_fd, (struct sockaddr *)&addr, &addrlen); @@ -609,9 +621,11 @@ int prefork_listen_recv(struct tevent_req *req, *fd = state->accept_fd; *srv_addr = talloc_move(mem_ctx, &state->srv_addr); *cli_addr = talloc_move(mem_ctx, &state->cli_addr); - state->pf->status = PF_WORKER_BUSY; state->pf->num_clients++; } + if (state->pf->status == PF_WORKER_ACCEPTING) { + state->pf->status = PF_WORKER_ALIVE; + } tevent_req_received(req); return ret; -- cgit