Ooops.  Reposted, changing:
> I see a problem with both "prestart" and "start" indicating "first time"
changed to:
> I see a problem with both "prestart" and "graceful" indicating "first time"
Sorry.  -Glenn


On Mon, Oct 27, 2003 at 04:53:22PM -0800, Stas Bekman wrote:
> Sander Striker wrote:
> I thought that this and my previous post's patch could be combined into one 
> API. So we could have the following states:
> 
> state      httpd.conf parsed # of times
> ---------------------------------------
> prestart     first time
> start        second time
> graceful     first time
> restart      first time
> stop         first time
> 
> the first two states are the normal startup, phases. As you can see from 
> this table, the state gives a better state mapping, rather then the 
> currently used init_if_first_time.

Doesn't "graceful" re-run both first and second configuration phases?

Couldn't "stop" be used to execute code as an AP-style atexit()/on_exit()?
If so, the function would need to return some alternate code besides
"first time" or "second time".

I see a problem with both "prestart" and "graceful" indicating "first time"
because memory pools are cleared after preflight and after graceful.
Some modules might need to do some memory allocation during what you call
the "start" phase.  You would not want to do this during "prestart"
because it would be cleared.  But you would want it to run after
"graceful", because memory pools (except the main pool?) are cleared.
Doing it in child_init might be wasteful for forked MPMs, and a hassle to
do in child_init for threaded MPMs (e.g. having to keep tabs with SysV
conditionals PTHREAD_INIT_ONCE or atomics).  (Or should the plog log pool
be used here instead of the primary pool?)

Or am I confused about memory pools and Apache configuration phase passes?
(quite likely :o))

Prior to this thread, I had needed to keep this state myself and so I 
reworked my previously posted macros into something which could just as
easily be made a generic function.  It is included below, but not well
tested.  If any of the comments below are incorrect, I'd be thrilled if
someone would correct me.

Thanks.
Glenn

(Feel free to rename to AP_INIT_<state> or whatever)

/* Apache runs init routines twice.  This keeps state and returns which mode,
 * preflight (first pass through config) or runtime (second pass), the routine
 * is being called in.
 * (The pool must have the same lifetime as the server (i.e. s->process->pool)
 *  so that when server is restarted, the userdata set below will be cleaned up
 *  and the module will be reinitialized properly.  A file-scoped global flag
 *  is not suitable for this purpose.)
 * (modified from Apache2 modules/generators/mod_cgid.c)
 */
enum { INIT_PREFLIGHT = 0, INIT_RUNTIME, INIT_DONE };
#  define INIT_MODE(mode, pool, tag)                                    \
    do {                                                                \
        void *userdata_data;                                            \
        apr_pool_userdata_get(&userdata_data, tag "_init_once", (pool));\
        if (userdata_data == NULL) {                                    \
            apr_pool_userdata_set((const void *)1, tag "_init_once",    \
                                  apr_pool_cleanup_null, (pool));       \
            (mode) = INIT_PREFLIGHT;                                    \
        }                                                               \
        else if (userdata_data == (const void *)1) {                    \
            apr_pool_userdata_set((const void *)2, tag "_init_once",    \
                                  apr_pool_cleanup_null, (pool));       \
            (mode) = INIT_RUNTIME;                                      \
        }                                                               \
        else {                                                          \
            (mode) = INIT_DONE;                                         \
        }                                                               \
    } while (0)


static int
example_init(apr_pool_t *p, apr_pool_t *l, apr_pool_t *t, server_rec *s)
{
    /* Check mode in which this code is being called: preflight, runtime, done*/
    int mode;
    INIT_MODE(mode, s->process->pool, "mod_example");

    /* (init routines should only be called twice, but be defensive) */
    if (mode != INIT_DONE) {
        ap_add_version_component("mod_example/"MOD_EXAMPLE_VERSION);
    }

    if (mode == INIT_PREFLIGHT) {
        /* Run as much as possible during first pass through the config
         * (so that certain errors can be detected early).
         * Do not run anything that depends on persistent memory pools,
         * which are cleared before the runtime pass through the config.
         * (or used the plog pool? (above as apr_pool_t *l))
         */

    }
    else if (mode == INIT_RUNTIME) {
        /* Run things dependent on persistent memory pools in second init pass*/

    }
    else { /* (mode == INIT_DONE) */
        /* (When (if at all) does this happen?
         *  Will this happen when shutting down?
         *  Only when shutting down?)
         */
    }

    return OK;
}

Reply via email to