开发者

Init modules in apache2

I used to write apache modules in apache 1.3, but these days I am willing to pass to apache2. The module that I am writing at the moment has is own binary data, not a database, for performance purposes. I need to load this data in shared memory, so every child can access it without making his own copy, and it would be pract开发者_如何学运维ical to load/create the binary data at startup, as I was used to do with apache 1.3. Problem is that I don't find an init event in apache2, in 1.3 in the module struct, immediatly after STANDARD_MODULE_STUFF you find a place for a /** module initializer */, in which you can put a function that will be executed early. Body of the function I used to write is something like:

if ( getppid == 1 )
{
     // Load global data here
     // this is the parent process
     void* data = loadGlobalData( someFilePath );
     setGlobalData( config, data );
}
else
{
    // this is the init of a child process
    // do nothing
}

I am looking for a place in apache2 in where I can put a similar function.

Can you help?

Thanks Benvenuto


Since you want the server to create a single shared memory segment to be used by all children, I would recommend initialising this in the post config hook (ap_hook_post_config). This is called once the configuration has been read, but before the children are spawned, so it should work well.


Since Apache 2.x loads DSO modules twice, ap_hook_post_config() is called twice during Apache startup.

The following code added to the ap_hook_post_config() will prevent the initialization of your module during the first call and continue only during the second call.

This is a hack, but a neat hack :)

void *data = NULL;
const char *key = "dummy_post_config";

// This code is used to prevent double initialization of the module during Apache startup
apr_pool_userdata_get(&data, key, s->process->pool);
if ( data == NULL ) { 
    apr_pool_userdata_set((const void *)1, key, apr_pool_cleanup_null, s->process->pool);
    return OK; 
}

You can read more about double dso module loads on the Apache wiki.


You can use a child_init hook to initialize a resource that will last longer then request or connection.

typedef struct {
    apr_pool_t *pool;
    apr_hash_t *hash;
} my_server_config;

static void my_child_init(apr_pool_t *p, server_rec *s)
{
    my_server_config cfg = ap_get_module_config(s->module_config, &my_module);
    /* Create sub-pool: ap_pool_create(&cfg->pool, p); */
    /* Create hash: cfg->hash = ap_hash_make(cfg->pool); */
}

static void my_register_hooks(apr_pool_t *p)
{
    ap_hook_child_init(my_child_init, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA my_module =
{
    STANDARD20_MODULE_STUFF,
    NULL,  /* per-directory config creator */
    NULL,  /* dir config merger */
    NULL,  /* server config creator */
    NULL,  /* server config merger */
    NULL,  /* command table */
    my_register_hooks, /* set up other request processing hooks */
};

Child init hook will be called before apache enters operational mode or before threads are created in threaded MPM. The pool passed into the my_child_init function should be process pool.

For better example you should download apache source code and check the modules/experimental/mod_example.c file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜