Commit b157f5b5 authored by Jeff Trawick's avatar Jeff Trawick
Browse files

end-generation hook: Fix false notification of end-of-generation for

temporary intervals with no active MPM children.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1200449 13f79535-47bb-0310-9956-ffa450edef68
parent be17e981
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.3.16

  *) end-generation hook: Fix false notification of end-of-generation for
     temporary intervals with no active MPM children.  [Jeff Trawick]

  *) mod_ssl: Add support for RFC 5077 TLS Session tickets.
     [Paul Querna]

+5 −0
Original line number Diff line number Diff line
@@ -136,6 +136,11 @@ void ap_register_extra_mpm_process(pid_t pid, ap_generation_t gen);
 */
int ap_unregister_extra_mpm_process(pid_t pid, ap_generation_t *old_gen);

/**
 * Pool cleanup for end-generation hook implementation
 */
apr_status_t ap_mpm_end_gen_helper(void *unused);

/**
 * Safely signal an MPM child process, if the process is in the
 * current process group.  Otherwise fail.
+2 −0
Original line number Diff line number Diff line
@@ -4389,6 +4389,8 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
                     "or other system security module is loaded.");
        return !OK;
    }
    apr_pool_cleanup_register(pconf, NULL, ap_mpm_end_gen_helper,
                              apr_pool_cleanup_null);
    return OK;
}

+46 −7
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ typedef struct mpm_gen_info_t {
    APR_RING_ENTRY(mpm_gen_info_t) link;
    int gen;          /* which gen? */
    int active;       /* number of active processes */
    int done;         /* gen finished? (whether or not active processes) */
} mpm_gen_info_t;

APR_RING_HEAD(mpm_gen_info_head_t, mpm_gen_info_t);
@@ -413,9 +414,50 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
    return rv;
}

static void end_gen(mpm_gen_info_t *gi)
{
    ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
                 "end of generation %d", gi->gen);
    ap_run_end_generation(ap_server_conf, gi->gen);
    APR_RING_REMOVE(gi, link);
    APR_RING_INSERT_HEAD(unused_geninfo, gi, mpm_gen_info_t, link);
}

apr_status_t ap_mpm_end_gen_helper(void *unused) /* cleanup on pconf */
{
    int gen = ap_config_generation - 1; /* differs from MPM generation */
    mpm_gen_info_t *cur;

    if (geninfo == NULL) {
        /* initial pconf teardown, MPM hasn't run */
        return APR_SUCCESS;
    }

    cur = APR_RING_FIRST(geninfo);
    while (cur != APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link) &&
           cur->gen != gen) {
        cur = APR_RING_NEXT(cur, link);
    }

    if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) {
        /* last child of generation already exited */
        ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
                     "no record of generation %d", gen);
    }
    else {
        cur->done = 1;
        if (cur->active == 0) {
            end_gen(cur);
        }
    }

    return APR_SUCCESS;
}

/* core's child-status hook
 * tracks number of remaining children per generation and
 * runs the end-generation hook when a generation finishes
 * runs the end-generation hook when the last child of
 * a generation exits
 */
void ap_core_child_status(server_rec *s, pid_t pid,
                          ap_generation_t gen, int slot,
@@ -446,6 +488,7 @@ void ap_core_child_status(server_rec *s, pid_t pid,
            if (!APR_RING_EMPTY(unused_geninfo, mpm_gen_info_t, link)) {
                cur = APR_RING_FIRST(unused_geninfo);
                APR_RING_REMOVE(cur, link);
                cur->active = cur->done = 0;
            }
            else {
                cur = apr_pcalloc(s->process->pool, sizeof *cur);
@@ -466,12 +509,8 @@ void ap_core_child_status(server_rec *s, pid_t pid,
        }
        else {
            --cur->active;
            if (!cur->active) {
                ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
                             "end of generation %d", gen);
                ap_run_end_generation(ap_server_conf, gen);
                APR_RING_REMOVE(cur, link);
                APR_RING_INSERT_HEAD(unused_geninfo, cur, mpm_gen_info_t, link);
            if (!cur->active && cur->done) { /* no children, server has stopped/restarted */
                end_gen(cur);
            }
        }
        break;