2010-04-30 74 views
4

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

你能幫忙嗎?

感謝 韋努託

回答

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文件。

3

由於您希望服務器創建一個由所有子級使用的共享內存段,因此我建議在後配置掛鉤(ap_hook_post_config)中初始化該內存段。一旦配置被讀取,但在子代產生之前調用它,所以它應該工作得很好。

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模塊的負載。

相關問題