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,
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,
}
int prefork_add_children(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx,
struct prefork_pool *pfp,
int num_children)
{
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,
* 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
* @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,
/**
* @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
*
* @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,
* @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
*
* 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);
/**
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;
}
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,
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);
}
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));
}
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;
}
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));
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,
/* 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,
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);