【问题标题】:Init modules in apache2apache2中的初始化模块
【发布时间】:2011-02-14 03:32:10
【问题描述】:

我以前在 apache 1.3 中编写 apache 模块,但这些天我愿意传递给 apache2。出于性能目的,我目前正在编写的模块是自己的二进制数据,而不是数据库。我需要将这些数据加载到共享内存中,这样每个孩子都可以在不制作自己的副本的情况下访问它,并且在启动时加载/创建二进制数据是很实用的,就像我以前使用 apache 1.3 所做的那样。问题是我没有在 apache2 中找到 init 事件,在 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 中寻找可以放置类似功能的地方。

你能帮忙吗?

谢谢 本韦努托

【问题讨论】:

    标签: apache module apache2 initialization


    【解决方案1】:

    由于您希望服务器创建一个供所有子代使用的共享内存段,我建议在 post config hook (ap_hook_post_config) 中初始化它。在读取配置后调用,但在子级生成之前调用,因此它应该可以正常工作。

    【讨论】:

      【解决方案2】:

      由于 Apache 2.x 两次加载 DSO 模块,因此 ap_hook_post_config() 在 Apache 启动期间被调用了两次。

      添加到 ap_hook_post_config() 的以下代码将阻止在第一次调用期间初始化您的模块,并且仅在第二次调用期间继续。

      这是一个 hack,但是一个巧妙的 hack :)

      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 模块加载的更多信息。

      【讨论】:

        【解决方案3】:

        您可以使用 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 中创建线程之前调用子初始化挂钩。传入 my_child_init 函数的池应该是进程池。

        为了更好的例子,你应该下载 apache 源代码并检查 modules/experimental/mod_example.c 文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-27
          • 2018-02-13
          • 1970-01-01
          • 1970-01-01
          • 2010-11-03
          • 2012-08-03
          • 1970-01-01
          • 2011-03-06
          相关资源
          最近更新 更多