httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sindhi Sindhi <sindhi....@gmail.com>
Subject Re: Apache: Create server config only once
Date Sun, 26 May 2013 05:39:40 GMT
Sorin! Thankyou so much, really appreciate your responses they are giving
me a very good insight.

On Sun, May 26, 2013 at 12:59 AM, Sorin Manolache <sorinm@gmail.com> wrote:

> On 2013-05-25 15:22, Sindhi Sindhi wrote:
>
>> Hi,
>>
>> I see that the create_server_config callback is called twice for every
>> Apache server startup. I want to do a lot of initialization in this
>> callback and allocations in this function are meant to be long lived. And
>> these buffers are very huge, so I want to ensure these initializations are
>> done only once per server start. As of now I'm trying to do the following
>> -
>>
>
> There's not much you can do against the double-call of create_*_config.
>
> Here's a rough sketch of how apache works:
>
> create conf pool
> create config objects for all modules and virtual hosts
> read config
> call pre_config callbacks
> parse config
> call post_config callbacks
>
> loop:
>    _clear the conf pool_
>    create config objects for all modules and virtual hosts
>    read config
>    call pre_config callbacks
>    parse config
>    call post_config callbacks
>    create generation of children to handle the requests
>    wait on the generation to die
>    if the signal was to stop => exit the loop
>    else (i.e. reload conf) iterate
>
> So apache invokes create_*_config twice before starting to handle the
> requests. But please note the following points:
>
> 1. The conf pool is cleared between the first and second call to
> create_*_config. So if you allocated something in create_*_config when it
> was called the first time you won't find it again when called the second
> time.
>
> 2. A new server_rec is constructed each time apache calls "create config
> objects for all modules and virtual hosts". This is why you don't find your
> conf object with ap_get_module_config.
>
> 3. The create_*_config callbacks are called not only at the beginning, but
> each time a new generation of children is spawned. An old generation is
> sent the message to shut down when apache is sent a signal, either to stop
> or to restart or to gracefully restart. Typically you want to reload the
> conf because you changed it, so it's normal that apache reparses the conf.
>
> What you could do is to create the conf in the first call. You also store
> it somewhere, let's say in a global variable. Then, in the second call, you
> do not try to get it from the server_rec (as anyway the server_rec is brand
> new and you would not find it there), but you get it from where you stored
> it in the first call.
>
> So something like that:
>
> static MyConf *my_global_conf;
>
> void *
> create_server_config() {
>    if (my_global_conf != NULL)
>        return my_global_conf;
>    my_global_conf = new MyConf;
>    return my_global_conf;
> }
>
> Note that if you adopt this approach you should not allocate anything in
> the pool that is passed to create_server_config because the pool is cleared
> between invocations.
>
> Also there are two problems with this approach:
>
> 1. You'll have one single object for all virtual hosts.
> 2. You cannot distinguish between the second call and subsequent calls. So
> you cannot do a conf reload (a graceful restart) anymore because all
> invocations of create_server_config except the first one will return the
> old my_global_conf and will not react to changes in the configuration. So
> you will be forced to do server restarts (as opposed to graceful restarts)
> in order to load a new configuration.
>
> My advice is to live with the double invocation because you gain more than
> you lose. It solves you the two problems mentioned above. You pay only by
> waiting a little longer at startup. Even if apache did not call the
> create_*_config functions twice before serving requests you would have to
> live with several invocations of the create_*_config callbacks if you want
> to support conf reloads. And conf reloads are very useful, you can reload
> the conf without losing requests.
>
> In order not to leak, place a cleanup function in the list of cleanup
> callbacks of the conf pool. For example:
>
> void *
> create_server_config(apr_pool_**t *pconf, ...) {
>    MyConf *cnf = new MyConf;
>    apr_pool_cleanup_register(**pconf, cnf, &my_cleanup,
> &apr_pool_cleanup_null);
>    return cnf;
> }
>
> apr_status_t
> my_cleanup(void *data) {
>    MyConf *cnf = reinterpret_cast<MyConf *>(data);
>    delete cnf;
>    return APR_SUCCESS;
> }
>
> my_cleanup will be called when the conf pool is cleared, i.e. before each
> new reparsing of the conf and creation of each new generation of children.
>
> Sorin
>
>
>
>> typedef struct
>> {
>> int bEnabled; // Enable or disable the module.
>> MyFilterInit* myFilterInitObj; // A class that has methods to do all huge
>> initializations
>> bool serverConfigured;
>> } MyFilterConfig;
>>
>> static int serverConfigHit = 0;
>>
>> static void* CreateServerConfig(apr_pool_t* pool, server_rec* virtServer)
>> {
>>      MyFilterConfig *pExistingConfig = (MyFilterConfig *)
>> ap_get_module_config (virtServer,  &tag_filter_module);
>>
>> if (serverConfigHit == 0) {
>> MyFilterConfig *pConfig = (MyFilterConfig *) apr_pcalloc (pool, sizeof
>> *pConfig);
>> pConfig->myFilterInitObj = new MyFilterInit(); // This does all the huge
>> initializations
>> serverConfigHit = serverConfigHit +1;
>> return pConfig;
>> }
>> return pExistingConfig;
>> }
>>
>> But I see an issue here. The second time when CreateServerConfig is
>> called,
>> 1. pExistingConfig is not having the address which was set during the
>> first
>> call to CreateServerConfig
>> 2. serverConfigHit is zero.
>>
>> Which means when CreateServerConfig was called first time, all the
>> initializations I made is not recorded by the server. Which means all the
>> allocations I made in the first call using malloc/new will result in a
>> memory leak.
>>
>> Kindly advice how do I ensure that my initializations are performed only
>> once.
>>
>> Thanks
>>
>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message