On Tue, Mar 29, 2016 at 1:39 PM, Tony Abo <t...@hitech.com> wrote:
>> > Is there a way to run some cleanup code in a module when the server is
>> being stopped, but not being restarted? Or, can a cleanup handler in a loaded
>> module determine whether the server is being shut down or restarted?
>>
>> With 2.4.x, you could use the ap_pglobal pool.
>>
>> Beware this should be done only once by register_hooks (called at every
>> restart), so something like:
>> {
>>     void *data;
>>
>>     apr_pool_userdata_get(&data, "my_module_key", ap_pglobal);
>>     if (!data) {
>>         char *key = apr_pstrdup(ap_pglobal, "my_module_key");
>>         apr_pool_userdata_set(key, key, apr_pool_cleanup_null, ap_pglobal);
>>     }
>> }
>
> Thanks for your suggestion. I am not yet on 2.4.x.
>
> Is ap_pglobal available to DSO modules?

It is, but not in versions prior to 2.4.x.

So you have to do differently, that is: get the process pool (which
has the lifetime of the parent process, declared as ap_pglobal in
2.4.x) from the configuration pool (the one passed to register_hooks,
which has the lifetime of a single (re)load).

Actually, the process pool is the parent pool of the configuration
pool, so you could do something like:

void my_register_hooks(apr_pool_t *p)
{
    apr_pool_t *pproc = apr_pool_parent_get(p);
    void *data;

    apr_pool_userdata_get(&data, "my_module_key", pproc);
    if (!data) {
        char *key = apr_pstrdup(pproc, "my_module_key");
        apr_pool_userdata_set(key, key, apr_pool_cleanup_null, pproc);

        /* your registering code here, eg.
        apr_pool_cleanup_register(pproc, my_cleanup_ctx, my_cleanup,
                                  apr_pool_cleanup_null);
        */
    }
}


>
> Also, if I register a cleanup handler for that pool, will the cleanup 
> function get called before my module is unloaded? I think in previous 
> versions the server unloads all of the loaded modules before destroying the 
> global pool. That would lead to a crash.

Yes, you have to take care of pools' lifetime.
The pproc above is the only one which is not cleared on restart, but
it's also the last one to be destroyed (on stop), hence my_cleanup
above must not access data allocated on any other pool (which would be
dead at the time the cleanup is called).

It means that resources accessed from the cleanup must also be
allocated on pproc, *or*, if this is an issue, you can use instead:
        apr_pool_pre_cleanup_register(pproc, my_cleanup_ctx, my_cleanup);
in my_register_hooks() above (note "pre_cleanup" instead of "cleanup").

By doing this, you are garanteed that the pre_cleanup will run
*before* any subpool (of pproc) is destroyed, and also before the
other (non pre_)cleanups registered (later) on pproc itself, thus
resources associated to (e.g.) the configuration pool would still be
accessible in the cleanup.

Hope this helps..

Regards,
Yann.

Reply via email to