Static Variables in Apache module are initialized more then once?
I wrote a module for Apache HTTP server and discovered strange behaviour. I've assumed that static variables are initialized only once, but I wrote the code below and made two requests to Apache the output was:
test_handler: isInit=0
test_handler: isInit=1
test_handlere: isInit=0
test_handlere: isInit=1
The test code:
static int isInit = 0;
static int test_handler( request_rec *r ) {
fprintf(stderr,"\n\natest_handler: isInit=%d", isInit );
if( !isInit ) {
isInit = 1;
}
fprintf(stderr,"\natest_handler: isInit=%d", isInit );
fflush(stderr);
return DECLINED;
}
static void register_hooks(apr_pool_t *p) {
fprintf(stdout,"register_hooks\n");
ap_hook_translate_name(test_handler, NULL, NULL, APR_HOOK_FIRST);
fprintf(stdout,"register_hooks done\n");
}
module AP_MODULE_DECLARE_DATA test_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
NULL, /* table of config file commands */
register_hooks /* register hooks */
};
The issue related to threads, since when I do 10 requests to Apache I see isInit=1, isInit=1
in some cases and isInit=0, isInit=1
开发者_JS百科 in others.
My question is, how I can define a variable, that will be accessible in test_handler()
and will preserve its value between calls to the function?
I think, I found the problem. Apache Server for Linux creates several 'child' servers to serve paralel requests. Every virtual sever loads configuration, including module instantces, so if ApacheServer creates 8 child server proccesses, you 8 copies of isInit variable. You can configure Apache to create obly one server ( not recommended - performance ). Another way is to configure Apache Server to use other Multi-Proccess technologies, I read abot prefork and worker. According to Apache2 documentation on Windows the server uses Windows API, so you can migrate to Windows or write module that can work as several paralel instances.
I think that it can be related with a race condition that occurs when several threads runs simultaneously. The keyword static
is only restricts the scope of the variable, so it's not a solution -- use something like mutexes
for the purpose of the race condition exclusion. Speaking about keeping some variable between a function calls within a connection you'll need to store this variable in connection-related structures (see request_rec->notes
or request_rec->connection->notes
for example).
精彩评论