s3-prefork: Pass messaging context around too
authorSimo Sorce <idra@samba.org>
Mon, 18 Jul 2011 14:39:50 +0000 (10:39 -0400)
committerAndreas Schneider <asn@samba.org>
Wed, 10 Aug 2011 16:14:04 +0000 (18:14 +0200)
Pair-Programmed-With: Andreas Schneider <asn@samba.org>

Signed-off-by: Andreas Schneider <asn@samba.org>
source3/lib/server_prefork.c
source3/lib/server_prefork.h
source3/printing/spoolssd.c

index 26288f70fd4e42c6d08783703251d98c665c71de..bc0f4c725ea12d5aeede6dce1298067f18893dbd 100644 (file)
@@ -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,
index c45b96975ab758d0e68ea51e9f6bb71376d33601..2f25e557fab6a7e921f635a895ece4d515e48cb8 100644 (file)
@@ -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);
 /**
index 107ae58fe43d133dafb3bd956739375c768d39cb..81bf7f876c001b27c30b60695b91121b00fd7dc0 100644 (file)
@@ -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);