Модули инициализации в apache2 - PullRequest
4 голосов
/ 30 апреля 2010

Раньше я писал модули apache в apache 1.3, но сейчас я готов перейти на apache2. Модуль, который я сейчас пишу, имеет собственные двоичные данные, а не базу данных, в целях повышения производительности. Мне нужно загрузить эти данные в разделяемую память, чтобы каждый ребенок мог получить к ней доступ, не создавая свою собственную копию, и было бы целесообразно загружать / создавать двоичные данные при запуске, как я привык делать с apache 1.3. Проблема в том, что я не нахожу событие init в apache2, в 1.3 в структуре модуля, сразу после 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, где я могу разместить аналогичную функцию.

Вы можете помочь?

Спасибо Бенвенуто

Ответы [ 3 ]

3 голосов
/ 13 мая 2010

Поскольку вы хотите, чтобы сервер создавал один сегмент совместно используемой памяти, который использовался бы всеми дочерними элементами, я бы рекомендовал инициализировать это в ловушке post config (ap_hook_post_config). Это вызывается после прочтения конфигурации, но до появления потомков, поэтому она должна хорошо работать.

3 голосов
/ 26 апреля 2013

Поскольку Apache 2.x дважды загружает модули DSO, ap_hook_post_config () вызывается дважды при запуске Apache.

Следующий код, добавленный к 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; 
}

Подробнее о двойной загрузке модуля dso вы можете прочитать на Apache wiki .

1 голос
/ 06 мая 2010

Вы можете использовать ловушку 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 */
};

Дочерняя инициализация init будет вызвана до того, как apache перейдет в рабочий режим или до того, как потоки будут созданы в многопоточном MPM. Пул, переданный в функцию my_child_init, должен быть пулом процесса.

Для лучшего примера вы должны скачать исходный код apache и проверить файл modules / экспериментальный / mod_example.c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...