apache2中的Init模块

问题描述:

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

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的地方在我可以把类似的功能。

你能帮忙吗?

感谢 韦努托

可以使用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文件。

由于您希望服务器创建一个由所有子级使用的共享内存段,因此我建议在后配置挂钩(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 wiki双DSO模块的负载。