diff options
-rw-r--r-- | source3/lib/server_prefork.c | 11 | ||||
-rw-r--r-- | source3/lib/server_prefork.h | 11 | ||||
-rw-r--r-- | source3/printing/spoolssd.c | 57 |
3 files changed, 59 insertions, 20 deletions
diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c index 26288f70fd..bc0f4c725e 100644 --- a/source3/lib/server_prefork.c +++ b/source3/lib/server_prefork.c @@ -54,7 +54,9 @@ static int prefork_pool_destructor(struct prefork_pool *pfp) return 0; } -bool prefork_create_pool(struct tevent_context *ev_ctx, TALLOC_CTX *mem_ctx, +bool prefork_create_pool(TALLOC_CTX *mem_ctx, + struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, int listen_fd_size, int *listen_fds, int min_children, int max_children, prefork_main_fn_t *main_fn, void *private_data, @@ -118,7 +120,8 @@ bool prefork_create_pool(struct tevent_context *ev_ctx, TALLOC_CTX *mem_ctx, case 0: /* THE CHILD */ pfp->pool[i].status = PF_WORKER_IDLE; - ret = pfp->main_fn(ev_ctx, &pfp->pool[i], + ret = pfp->main_fn(ev_ctx, msg_ctx, + &pfp->pool[i], pfp->listen_fd_size, pfp->listen_fds, pfp->lock_fd, @@ -175,6 +178,7 @@ int prefork_expand_pool(struct prefork_pool *pfp, int new_max) } int prefork_add_children(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, struct prefork_pool *pfp, int num_children) { @@ -201,7 +205,8 @@ int prefork_add_children(struct tevent_context *ev_ctx, case 0: /* THE CHILD */ pfp->pool[i].status = PF_WORKER_IDLE; - ret = pfp->main_fn(ev_ctx, &pfp->pool[i], + ret = pfp->main_fn(ev_ctx, msg_ctx, + &pfp->pool[i], pfp->listen_fd_size, pfp->listen_fds, pfp->lock_fd, diff --git a/source3/lib/server_prefork.h b/source3/lib/server_prefork.h index c45b96975a..2f25e557fa 100644 --- a/source3/lib/server_prefork.h +++ b/source3/lib/server_prefork.h @@ -62,6 +62,7 @@ struct pf_worker_data { * cause the termination of the child. * * @param ev The event context +* @param msg_ctx The messaging context * @param pf The mmaped area used to communicate with parent * @param listen_fd_size The number of file descriptors to monitor * @param listen_fds The array of file descriptors @@ -72,6 +73,7 @@ struct pf_worker_data { * @return Returns the exit status to be reported to the parent via exit() */ typedef int (prefork_main_fn_t)(struct tevent_context *ev, + struct messaging_context *msg_ctx, struct pf_worker_data *pf, int listen_fd_size, int *listen_fds, @@ -94,8 +96,9 @@ typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx, /** * @brief Creates the first pool of preforked processes * -* @param ev_ctx The event context * @param mem_ctx The memory context used to hold the pool structure +* @param ev_ctx The event context +* @param msg_ctx The messaging context * @param listen_fd_size The number of file descriptors to monitor * @param listen_fds The array of file descriptors to monitor * @param min_children Minimum number of children that must be available at @@ -108,7 +111,9 @@ typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx, * * @return True if it was successful, False otherwise. */ -bool prefork_create_pool(struct tevent_context *ev_ctx, TALLOC_CTX *mem_ctx, +bool prefork_create_pool(TALLOC_CTX *mem_ctx, + struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, int listen_fd_size, int *listen_fds, int min_children, int max_children, prefork_main_fn_t *main_fn, void *private_data, @@ -132,6 +137,7 @@ int prefork_expand_pool(struct prefork_pool *pfp, int new_max); * @brief Used to prefork a number of new children * * @param ev_ctx The event context +* @param msg_ctx The messaging context * @param pfp The pool structure * @param num_children The number of children to be started * @@ -141,6 +147,7 @@ int prefork_expand_pool(struct prefork_pool *pfp, int new_max); * has already been forked it will do nothing. */ int prefork_add_children(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, struct prefork_pool *pfp, int num_children); /** diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c index 107ae58fe4..81bf7f876c 100644 --- a/source3/printing/spoolssd.c +++ b/source3/printing/spoolssd.c @@ -357,13 +357,13 @@ struct spoolss_children_data { static void spoolss_next_client(void *pvt); static int spoolss_children_main(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, struct pf_worker_data *pf, int listen_fd_size, int *listen_fds, int lock_fd, void *private_data) { - struct messaging_context *msg_ctx = server_messaging_context(); struct spoolss_children_data *data; bool ok; int ret; @@ -538,6 +538,7 @@ static void check_updater_child(void) } static bool spoolssd_schedule_check(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, struct prefork_pool *pfp, struct timeval current_time); static void spoolssd_check_children(struct tevent_context *ev_ctx, @@ -547,11 +548,14 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx, static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx, struct prefork_pool *pfp, - void *private_data) + void *pvt) { + struct messaging_context *msg_ctx; int active, total; int n, r; + msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); + /* now check we do not descend below the minimum */ active = prefork_count_active_children(pfp, &total); @@ -563,7 +567,7 @@ static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx, } if (n > 0) { - r = prefork_add_children(ev_ctx, pfp, n); + r = prefork_add_children(ev_ctx, msg_ctx, pfp, n); if (r < n) { DEBUG(10, ("Tried to start %d children but only," "%d were actually started.!\n", n, r)); @@ -575,35 +579,54 @@ static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx, } static bool spoolssd_setup_children_monitor(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, struct prefork_pool *pfp) { bool ok; /* add our oun sigchld callback */ - prefork_set_sigchld_callback(pfp, spoolssd_sigchld_handler, NULL); + prefork_set_sigchld_callback(pfp, spoolssd_sigchld_handler, msg_ctx); - ok = spoolssd_schedule_check(ev_ctx, pfp, tevent_timeval_current()); + ok = spoolssd_schedule_check(ev_ctx, msg_ctx, pfp, + tevent_timeval_current()); return ok; } +struct schedule_check_state { + struct messaging_context *msg_ctx; + struct prefork_pool *pfp; +}; + static bool spoolssd_schedule_check(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, struct prefork_pool *pfp, struct timeval current_time) { struct tevent_timer *te; struct timeval next_event; + struct schedule_check_state *state; /* check situation again in 10 seconds */ next_event = tevent_timeval_current_ofs(10, 0); + state = talloc(ev_ctx, struct schedule_check_state); + if (!state) { + DEBUG(0, ("Out of memory!\n")); + return false; + } + state->msg_ctx = msg_ctx; + state->pfp = pfp; + /* TODO: check when the socket becomes readable, so that children * are checked only when there is some activity ? */ te = tevent_add_timer(ev_ctx, pfp, next_event, - spoolssd_check_children, pfp); + spoolssd_check_children, state); if (!te) { DEBUG(2, ("Failed to set up children monitoring!\n")); + talloc_free(state); return false; } + talloc_steal(te, state); return true; } @@ -613,25 +636,26 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx, struct timeval current_time, void *pvt) { - struct prefork_pool *pfp; + struct schedule_check_state *state; int active, total; int ret, n; - pfp = talloc_get_type_abort(pvt, struct prefork_pool); + state = talloc_get_type_abort(pvt, struct schedule_check_state); if ((spoolss_prefork_status & SPOOLSS_NEW_MAX) && !(spoolss_prefork_status & SPOLLSS_ENOSPC)) { - ret = prefork_expand_pool(pfp, spoolss_max_children); + ret = prefork_expand_pool(state->pfp, spoolss_max_children); if (ret == ENOSPC) { spoolss_prefork_status |= SPOLLSS_ENOSPC; } spoolss_prefork_status &= ~SPOOLSS_NEW_MAX; } - active = prefork_count_active_children(pfp, &total); + active = prefork_count_active_children(state->pfp, &total); if (total - active < spoolss_spawn_rate) { - n = prefork_add_children(ev_ctx, pfp, spoolss_spawn_rate); + n = prefork_add_children(ev_ctx, state->msg_ctx, + state->pfp, spoolss_spawn_rate); if (n < spoolss_spawn_rate) { DEBUG(10, ("Tried to start 5 children but only," "%d were actually started.!\n", n)); @@ -640,12 +664,13 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx, if (total - active > spoolss_min_children) { if ((total - spoolss_min_children) >= spoolss_spawn_rate) { - prefork_retire_children(pfp, spoolss_spawn_rate, + prefork_retire_children(state->pfp, spoolss_spawn_rate, time(NULL) - SPOOLSS_MIN_LIFE); } } - ret = spoolssd_schedule_check(ev_ctx, pfp, current_time); + ret = spoolssd_schedule_check(ev_ctx, state->msg_ctx, + state->pfp, current_time); } static void print_queue_forward(struct messaging_context *msg, @@ -723,7 +748,9 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx, /* start children before any more initialization is done */ - ok = prefork_create_pool(ev_ctx, ev_ctx, 1, &listen_fd, + ok = prefork_create_pool(ev_ctx, /* mem_ctx */ + ev_ctx, msg_ctx, + 1, &listen_fd, spoolss_min_children, spoolss_max_children, &spoolss_children_main, NULL, @@ -798,7 +825,7 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx, talloc_free(mem_ctx); - ok = spoolssd_setup_children_monitor(ev_ctx, pool); + ok = spoolssd_setup_children_monitor(ev_ctx, msg_ctx, pool); if (!ok) { DEBUG(0, ("Failed to setup children monitoring!\n")); exit(1); |