初始化模块在Apache2

我曾经在apache 1.3中编写apache模块,但是现在我愿意传给apache2。 目前我写的模块是自己的二进制数据,而不是数据库,出于性能目的。 我需要将这些数据加载到共享内存中,这样每个孩子都可以在不使用自己的副本的情况下访问它,并且在启动时加载/创build二进制数据是可行的,正如我以前用Apache 1.3所做的那样。 问题是,我没有在apache2中find一个init事件,在模块struct中的1.3中,在STANDARD_MODULE_STUFF之后立即find了一个/ **模块初始化程序* /的地方,在这个地方你可以放一个将被执行的函数。 我用来写的函数体是这样的:

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 } 

我正在寻找一个地方在apache2在哪里我可以把类似的function。

你能帮我吗?

谢谢Benvenuto

既然你想要服务器创建一个单独的共享内存段供所有的孩子使用,我会建议在后置配置钩子(ap_hook_post_config)中初始化这个。 一旦配置已经被读取,但是在孩子产生之前,这就被调用,所以它应该工作得很好。

由于Apache 2.x加载DSO模块两次,因此在Apache启动期间将调用ap_hook_post_config()两次。

下面的代码添加到ap_hook_post_config()将阻止在第一次调用期间模块的初始化,并只在第二次调用期间继续。

这是一个黑客,但一个整洁的黑客:)

 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; } 

你可以阅读更多关于Apache维基上的double dso模块加载。

您可以使用child_init挂钩来初始化资源,该资源将持续更长的时间,然后请求或连接。

 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 */ }; 

在apache进入操作模式之前或在线程MPM中创建线程之前,将调用Child init钩子。 传入my_child_init函数的池应该是进程池。

为了更好的例子,你应该下载apache源代码并检查modules / experimental / mod_example.c文件。