2010-04-30 7 views
4

J'avais l'habitude d'écrire des modules Apache dans Apache 1.3, mais ces jours-ci, je suis prêt à passer à Apache2. Le module que j'écris en ce moment a ses propres données binaires, pas une base de données, à des fins de performance. J'ai besoin de charger ces données dans la mémoire partagée, afin que chaque enfant puisse y accéder sans faire sa propre copie, et il serait pratique de charger/créer les données binaires au démarrage, comme je le faisais avec Apache 1.3. Le problème est que je ne trouve pas d'événement init dans apache2, en 1.3 dans le module struct, immédiatement après STANDARD_MODULE_STUFF vous trouvez une place pour un initialiseur/** module *, dans lequel vous pouvez mettre une fonction qui sera exécutée tôt . corps de la fonction, je l'habitude d'écrire est quelque chose comme:Init modules dans apache2

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 
} 

Je cherche une place dans apache2 dans où je peux mettre une fonction similaire.

Pouvez-vous m'aider?

Merci Benvenuto

Répondre

1

Vous pouvez utiliser un crochet child_init pour initialiser une ressource qui va durer plus ou alors demander la connexion.

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

Le hook init init sera appelé avant que apache ne passe en mode opérationnel ou avant que les threads ne soient créés dans MPM threadé. Le pool passé dans la fonction my_child_init doit être un pool de processus. Pour un meilleur exemple, vous devez télécharger le code source Apache et vérifier le fichier modules/experimental/mod_example.c.

3

Puisque vous voulez que le serveur crée un seul segment de mémoire partagée à utiliser par tous les enfants, je recommanderais de l'initialiser dans le hook post-config (ap_hook_post_config). Ceci est appelé une fois que la configuration a été lue, mais avant que les enfants soient engendrés, cela devrait bien fonctionner.

3

Comme Apache 2.x charge les modules DSO deux fois, ap_hook_post_config() est appelée deux fois au démarrage d'Apache. Le code suivant ajouté à ap_hook_post_config() empêchera l'initialisation de votre module pendant le premier appel et se poursuivra uniquement pendant le second appel.

C'est un hack, mais un hack net :)

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

Vous pouvez en savoir plus sur doubles charges module DSO sur le Apache wiki.