• apache2 流程控制


    _hook 数据结构
     1 
     2 // 从 ap_hook 到 ap_run
     3 // 宏 AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c, void *csd),(c, csd),OK,DECLINED ); 的具体实现
     4 // connection.c
     5     AP_DECLARE(void) ap_hook_pre_connection(ap_HOOK_pre_connection_t *pf, const char * const *aszPre, const char * const *aszSucc,int nOrder)
     6     { 
     7         ap_LINK_pre_connection_t *pHook; 
     8         if(!_hooks.link_pre_connection)
     9         {
    10             _hooks.link_pre_connection=apr_array_make(apr_hook_global_pool,1,sizeof(ap_LINK_pre_connection_t)); 
    11             apr_hook_sort_register("pre_connection",&_hooks.link_pre_connection); 
    12         } 
    13         pHook=apr_array_push(_hooks.link_pre_connection); 
    14         pHook->pFunc=pf; 
    15         pHook->aszPredecessors=aszPre; 
    16         pHook->aszSuccessors=aszSucc; 
    17         pHook->nOrder=nOrder; 
    18         pHook->szName=apr_hook_debug_current; 
    19         if(apr_hook_debug_enabled) 
    20             apr_hook_debug_show("pre_connection",aszPre,aszSucc); 
    21     } 
    22     AP_DECLARE(apr_array_header_t *) ap_hook_get_pre_connection(void
    23     { 
    24         return _hooks.link_pre_connection; 
    25     }
    26     AP_DECLARE(int) ap_run_pre_connection (conn_rec *c, void *csd)
    27     { 
    28         ap_LINK_pre_connection_t *pHook; int n; int rv; 
    29         if(!_hooks.link_pre_connection) 
    30             return OK; 
    31         pHook=(ap_LINK_pre_connection_t *)_hooks.link_pre_connection->elts; 
    32         for(n=0 ; n < _hooks.link_pre_connection->nelts ; ++n)
    33         { 
    34             rv=pHook[n].pFunc (c, csd); 
    35             if(rv != OK && rv != DECLINED) return rv;
    36         } 
    37         return OK; 
    38     };

    解码解释:

    第5行 ap_hook_pre_connection 的第一个参数 pf 数据类型为 ap_HOOK_pre_connection_t ,实际是一个函数指针。也是用宏定义的:

    // 宏 AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c, void *csd))展开
    // http_connection.h
    typedef int ap_HOOK_pre_connection_t (conn_rec *c, void *csd);

    AP_DECLARE(
    void) ap_hook_pre_connection(ap_HOOK_pre_connection_t *pf, const char * const *aszPre, const char * const *aszSucc, int nOrder); 
    AP_DECLARE(
    int) ap_run_pre_connection (conn_rec *c, void *csd); 
    AP_DECLARE(apr_array_header_t 
    *) ap_hook_get_pre_connection(void); 
    typedef 
    struct ap_LINK_pre_connection_t 
    {    
        ap_HOOK_pre_connection_t 
    *pFunc; 
        
    const char *szName; 
        
    const char * const *aszPredecessors; 
        
    const char * const *aszSuccessors; 
        
    int nOrder;
    } ap_LINK_pre_connection_t;

    第7 行的 _hook 定义于 connection.c ,它是一个由宏定义的文件级的变量。 

    从 hook 到 run--宏的展开
    展开 ap_hook_宏和 ap_run宏 
    /**
     * 展开 apache2 的 ap_hook_宏和  ap_run宏
     * 使用 gcc -E -I/usr/local/apache2/include macos.h 可得到实际的c 代码
     * by fancp 2011-1-10 p_168@163.com
     * 
     **************************************************
    */
    #include 
    <ap_config.h>

    APR_HOOK_STRUCT(
        APR_HOOK_LINK(create_request_bin)
    )

    AP_DECLARE_HOOK(
    int,create_request_bin,(conn_rec *c, void *csd))


    AP_IMPLEMENT_HOOK_RUN_ALL(
    int, create_request_bin,
                              (request_rec_bin 
    *r), (r), OK, DECLINED)

     



    ap_filter_rec_t 数据结构
    /***************************************
     * 
     * util_filter.h
     **************************************
    */
    struct ap_filter_rec_t {
        
    /** The registered name for this filter */
        
    const char *name;

        
    /** The function to call when this filter is invoked. */
        ap_filter_func filter_func;

        
    /** The function to call directly before the handlers are invoked
         * for a request.  The init function is called once directly
         * before running the handlers for a request or subrequest.  The
         * init function is never called for a connection filter (with
         * ftype >= AP_FTYPE_CONNECTION).  Any use of this function for
         * filters for protocols other than HTTP is specified by the
         * module supported that protocol.
         
    */
        ap_init_filter_func filter_init_func;

        
    /** The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION.  
         * An AP_FTYPE_CONTENT filter modifies the data based on information 
         * found in the content.  An AP_FTYPE_CONNECTION filter modifies the 
         * data based on the type of connection.
         
    */
        ap_filter_type ftype;

        
    /** The next filter_rec in the list */
        
    struct ap_filter_rec_t *next;

        
    /** Providers for this filter */
        ap_filter_provider_t 
    *providers;

        
    /** Trace level for this filter */
        
    int debug;

        
    /** Protocol flags for this filter */
        unsigned 
    int proto_flags;
    };
     
    /*
     * Read data from the next filter in the filter stack.  Data should be
     * modified in the bucket brigade that is passed in.  The core allocates the
     * bucket brigade, modules that wish to replace large chunks of data or to
     * save data off to the side should probably create their own temporary
     * brigade especially for that use.
     
    */
    AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t 
    *next,
                                            apr_bucket_brigade 
    *bb,
                                            ap_input_mode_t mode,
                                            apr_read_type_e block,
                                            apr_off_t readbytes)
    {
        
    if (next) {
            
    return next->frec->filter_func.in_func(next, bb, mode, block,
                                                   readbytes);
        }
        
    return AP_NOBODY_READ;
    }
     

    范晨鹏
    ------------------
    软件是一种态度
    成功是一种习惯


  • 相关阅读:
    Codeforces 401C Team 贪心法
    C++ 编译,执行过程 具体解释。
    [从头学数学] 第156节 概率初步
    关于flex,好像有12个属性非常重要
    数据清洗小记(12):姓与名的提取
    理解Angular中的$apply()以及$digest()
    Oracle开发者守则
    黑马程序猿——25,打印流,合并流,对象序列化,管道流,RandomAccessFile
    GPU 编程入门到精通(四)之 GPU 程序优化
    Python 面向对象编程 继承 和多态
  • 原文地址:https://www.cnblogs.com/diylab/p/1931691.html
Copyright © 2020-2023  润新知