You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by John Millaway <jo...@yahoo.com> on 2003/10/12 21:33:43 UTC

ap_process_config_tree called twice -- causes command_rec entries to be called twice -- httpd-2.0.47

Hi,

In httpd-2.0.47, command_rec entries are being called twice, via
ap_process_config_tree. The first call occurs at main.c:581, and the second
call occurs at main.c:638.  The result is that the callbacks in a module's
command_rec are called twice, as if the module's directives had appeared
twice in the httpd.conf file. Is this supposed to happen? -John



__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com

Re: ap_process_config_tree called twice -- causes command_rec entries to be called twice -- httpd-2.0.47

Posted by Glenn <gs...@gluelogic.com>.
On Sun, Oct 12, 2003 at 10:46:44PM +0200, Erik Abele wrote:
> Yes, this is the intended behaviour, there's even a comment at 
> main.c:564
> 
>     /* Note that we preflight the config file once
>      * before reading it _again_ in the main loop.
>      * This allows things, log files configuration
>      * for example, to settle down.
>      */
> 
> So, post_config hooks are always called twice.  You can see
> a working example in modules/mappers/mod_rewrite.c or in
> modules/generators/mod_cgid.c: there you'll find a flag
> called "first_time" in the post_config/cgid_init handler
> which takes care of the number of passes.

This response is slightly OT from the original question, but here's
what I have used in modules I've written.  Would there be any interest
in making these macros available to all modules?

Cheers,
Glenn


/* Apache runs init routines twice.  Set token to ensure things run only once.
 * (modified from Apache2 modules/generators/mod_cgid.c)
 * (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, unless it acts as a toggle and makes the
 *  assumption that init routines are always run twice, and exactly twice,
 *  (which is currently true AFAIK).
 *  The method below is safer.)
 */
#define RUN_INIT_ONCE(pool, tag)                                        \
    do {                                                                \
        void *userdata_data;                                            \
        apr_pool_userdata_get(&userdata_data, tag "_init_once", (pool));\
        if (userdata_data != NULL) {                                    \
            return OK;                                                  \
        }                                                               \
        apr_pool_userdata_set((const void *)1, tag "_init_once",        \
                              apr_pool_cleanup_null, (pool));           \
    } while (0)


static int
example_init(apr_pool_t *p, apr_pool_t *l, apr_pool_t *t, server_rec *s)
{
    /* ... code that can or should be run twice ... */

    /* Check that code in the rest of this routine has not already been run. */
    RUN_INIT_ONCE(s->process->pool, "mod_example"); /*(use unique module tag)*/

    /* ... code that must only be run the _first_ time init is called ... */

    return OK;
}


/* Or the inversion of the the macro behavior above */
#define RETURN_IF_PREFLIGHT(pool, tag)                                  \
    do {                                                                \
        void *userdata_data;                                            \
        apr_pool_userdata_get(&userdata_data, tag "_preflight", (pool));\
        if (userdata_data == NULL) {                                    \
            apr_pool_userdata_set((const void *)1, tag "_preflight",    \
                                  apr_pool_cleanup_null, (pool));       \
            return OK;                                                  \
        }                                                               \
    } while (0)


static int
example_init(apr_pool_t *p, apr_pool_t *l, apr_pool_t *t, server_rec *s)
{
    /* ... code that can or should be run twice ... */

    /* Do not run code in rest of this routine if preflight read of config */
    RETURN_IF_PREFLIGHT(s->process->pool, "mod_example");/*(unique module tag)*/

    /* ... code that must only be run the _second_ time init is called ... */

    return OK;
}

Re: ap_process_config_tree called twice -- causes command_rec entries to be called twice -- httpd-2.0.47

Posted by Erik Abele <er...@codefaktor.de>.
On 12/10/2003, at 09:33, John Millaway wrote:

> Hi,
>
> In httpd-2.0.47, command_rec entries are being called twice, via
> ap_process_config_tree. The first call occurs at main.c:581, and the 
> second
> call occurs at main.c:638.  The result is that the callbacks in a 
> module's
> command_rec are called twice, as if the module's directives had 
> appeared
> twice in the httpd.conf file. Is this supposed to happen? -John

Yes, this is the intended behaviour, there's even a comment at 
main.c:564

     /* Note that we preflight the config file once
      * before reading it _again_ in the main loop.
      * This allows things, log files configuration
      * for example, to settle down.
      */

So, post_config hooks are always called twice. You can see a working 
example
in modules/mappers/mod_rewrite.c or in modules/generators/mod_cgid.c: 
there
you'll find a flag called "first_time" in the post_config/cgid_init 
handler which takes
care of the number of passes.

Cheers,
Erik