我曾经在apache 1.3中编写apache模块,但是这些天我愿意传递给apache2。出于性能目的,我现在编写的模块是自己的二进制数据,而不是数据库。我需要将这些数据加载到共享内存中,这样每个孩子都可以在不创建自己的副本的情况下访问它,并且在启动时加载/创建二进制数据是可行的,就像我习惯使用apache 1.3一样。问题是我在模块结构中的1.3中没有在apache2中找到init事件,在STANDARD_MODULE_STUFF之后立即为/ **模块初始化器*找到了一个位置,你可以在其中放置一个将在早期执行的函数。 我以前写的函数的主体是这样的:
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中寻找一个可以放置类似功能的地方。
你能帮忙吗?
由于 本韦努托
答案 0 :(得分:3)
由于您希望服务器创建一个供所有孩子使用的单个共享内存段,我建议在post config hook(ap_hook_post_config)中初始化它。一旦读取了配置,就会在生成子项之前调用它,因此它应该可以正常工作。
答案 1 :(得分:3)
由于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 wiki上阅读有关双dso模块负载的更多信息。
答案 2 :(得分:1)
您可以使用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中创建线程之前,将调用子init挂钩。传入my_child_init函数的池应该是进程池。
为了更好的示例,您应该下载apache源代码并检查modules / experimental / mod_example.c文件。