锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 英语翻译 / mod_perl特有的功能流
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。需要全文内容也请联系孙老师。

mod_perl特有的功能流

1.1 Description 描述

This document attempts to help understand the code flow for certain features. This should help to de+bug problems and add new features. 本文试图帮助理解代码流某的些特性。这应该有助于调试问题和添加新特性。

This document auguments mod_perl internals: Apache 2.0 Integration and discusses the internals of the mod_perl-specific features. 本文关注mod_perl的内部:Apache 2.0的集成和讨论mod_perl的专有功能的内部。

Make sure to read also: Debugging mod_perl C Internals. 请务必同时阅读:调试的mod_perl Ç 内幕。

META: these notes are a bit out of sync with the latest cvs, but will be updated once the innovation dust settles down. META:这些笔记都有点出与最新的CVS同步的,但一旦更新风波平息下来,将被更新。

1.2 Perl Interpreters Perl解释器

How and when Perl interpreters are created:如何以及何时创建Perl解释器:

1. modperl_hook_init is invoked by one of two paths: Either normally, during the open_logs phase, or during the configuration parsing if a directive needs perl at the early stage (e.g. PerlLoadModule). modperl hook_init是通过两条路径调用:无论是正常在open_logs阶段,或在配置过程中解析如果一条指令在早期阶段(例如Perl中的LoadModule)需要Perl。

ap_hook_open_logs() -> # normal mod_perl startup

load_module() -> modperl_run() -> # early startup caused by PerlLoadModule

2. modperl_hook_init() -> modperl_init():
o modperl_startup()
- parent perl is created and started ("-e0"),
- top level PerlRequire and PerlModule are run
o modperl_interp_init()
- modperl_tipool_new() # create/init tipool
- modperl_interp_new() # no new perls are created at this stage
o modperl_init_vhost() # vhosts are booted, for each vhost run:
if +Parent
- modperl_startup() # vhost gets its own parent perl (not perl_clone()!)
else
- vhost’s PerlModule/PerlRequire directives are run if any
if +(Parent|Clone)
- modperl_interp_init() (new tipool, no new perls created)

3. Next the post_config hook is run. It immediately returns for non-threaded mpms. Otherwise that’s where all the first clones are created (and later their are created on demand when there aren’t enough in the pool and more are needed). 下一个post_config运行。它立即返回线程mpm。否则这是所有第一个克隆创建位置(后来他们当没有足够的需求创建,更需要)。
o modperl_init_clones() creates pools of clones
- modperl_tipool_init() (clones the PerlStartInterp number of perls)
- interp_pool_grow()
- modperl_interp_new()
~ this time perl_clone() is called
~ PL_ptr_table is scratched
modperl_xs_dl_handles_clear

1.3 Filters 过滤器

Apache filters work in the following way. First of all, a filter must be registered by its name, in addition providing a pointer to a function that should be executed when the filter is called and the type of resources it should be called on (e.g., only request’s body, the headers, both and others). Once registered, the filter can be inserted into a chain of filters to be executed at run time.

Apache过滤器在以下方式工作。首先,必须通过它的名称注册一个过滤器,此外提供一个指向函数的指针,调用过滤器时应该执行的功能和资源的类型(例如,唯一的要求的机构,头文件,和其他)。一旦注册,过滤器可以插入到过滤器链,进而在运行时可执行。

For example in the pre_connection phase we can add connection phase filters, and using the ap_hook_insert_filter we can call functions that add the current request’s filters. The filters are added using their registered name and a special context variable, which is typed to (void *) so modules can store anything they want there. You can add more than one filter with the same name to the same filter chain.

例如在pre_connection阶段,我们可以添加连接阶段过滤器,和使用ap_hook_insert_filter我们可以调用一些函数,这些函数被添加当前请求的过滤器内。使用他们的注册名和一个特殊的上下文变量来添加过滤器,变量是(void *)类型的,所以模块可以存储任何他们想要的。您可以添加多个具有相同名称的相同过滤器链。

Here is how mod_perl uses this infrastructure: There can be many filters inserted via mod_perl, but they all seen by Apache by four filter names: mod_perl如何使用这个基础设施: 可以有许多过滤器通过mod_perl插入,但他们都被四个Apache过滤器看到名字

MODPERL_REQUEST_OUTPUT
MODPERL_REQUEST_INPUT
MODPERL_CONNECTION_OUTPUT
MODPERL_CONNECTION_INPUT

XXX: which actually seems to be lowercased by Apache (saw it in gdb), (it handles these in the case insensitive manner?). how does then modperl_filter_add_request works, as it compares *fname with M. XXX:实际上似乎是小写的Apache(gdb看到它),(它处理这些情况不区分大小写),modperl_filter_add_request如何工作,就像它比较帧与M。

These four filter names are registered in modperl_register_hooks(): 这四个过滤器在modperl_register_hooks注册的名字是():
ap_register_output_filter(MP_FILTER_REQUEST_OUTPUT_NAME,
MP_FILTER_HANDLER(modperl_output_filter_handler),
AP_FTYPE_RESOURCE);
ap_register_input_filter(MP_FILTER_REQUEST_INPUT_NAME,
MP_FILTER_HANDLER(modperl_input_filter_handler),
AP_FTYPE_RESOURCE);
ap_register_output_filter(MP_FILTER_CONNECTION_OUTPUT_NAME,
MP_FILTER_HANDLER(modperl_output_filter_handler),
AP_FTYPE_CONNECTION);
ap_register_input_filter(MP_FILTER_CONNECTION_INPUT_NAME,
MP_FILTER_HANDLER(modperl_input_filter_handler),
AP_FTYPE_CONNECTION);

At run time input filter handlers are always called by modperl_input_filter_handler() and output filter handler by modperl_output_filter_handler(). For example if there are three MODPERL_CONNECTION_ INPUT filters in the filters chain, modperl_input_filter_handler() will be called three times.
在运行时输入滤波器处理程序和输出滤波器处理程序总是被modperl_output_filter_handler()访问。例如,如果有在过滤器链中有三个MODPERL CONNECTION_INPUT滤波器,modperl_input_filter_handler()将被访问三次。

The real Perl filter handler (callback) is stored in ctx->handler, which is retrieved by modperl_{output|input}_filter_handler and run as a normal Perl handler by modperl_run_filter() via modperl_callback(): 真正的Perl滤波器处理器(回调)被存储在ctx->处理程序,是由modperl_{输出|输入检索}和_filter_handler运行由modperl_run_filter()通过mod_perl的回调()一个正常的Perl处理器:

retrieve ctx->handler
modperl_output_filter_handler -> modperl_run_filter -> modperl_callback

This trick allows to have more than one filter handler in the filters chain using the same Apache filter name (the real filter’s name is stored in ctx->handler->name. 这种方法允许有多个过滤器处理程序在过滤器链中使用相同的Apache过滤器名称(真正的过滤器的名字是存储在ctx->处理程序- >名称。

Now the only missing piece in the puzzle is how and when mod_perl filter handlers are inserted into the filter chain. It happens in three stages. 现在,在拼图中唯一缺失的部分是如何以及何时mod_perl的过滤器处理程序插入到过滤器链。它发生在三个阶段。

1. When the configuration file is parsed, every time a PerlInputFilterHandler or a PerlOutputFilterHandler directive is encountered, its argument (filter handler) is inserted into dcfg->handlers_per_dir[idx] by modperl_cmd_input_filter_handlers() and modperl_cmd_output_filter_handlers(). idx is either MP_INPUT_FILTER_HANDLER or MP_OUTPUT_FILTER_HANDLER. Since they are stored in the dcfg struct, normal merging of parent and child directories applies.

在解析配置文件时,每次PerlInputFilterHandler或PerlOutputFilterHandler遇到指令,其参数(过滤器处理程序)插入dcfg-> handlers_per_dir[idx],这是由modperl_cmd_input_filter_handlers()和modperl_cmd_output_filter_handlers()完成.idx要么是MP_INPUT_FILTER_HANDLER或MP_OUTPUT_FILTER_HANDLER。由于它们存储在DCFG结构,父进程和子目录正常合并适用。

2. Next, modperl_hook_post_config calls modperl_mgv_hash_handlers which works through dcfg->handlers_per_dir[idx] and resolves the handlers (via modperl_mgv_resolve), so they are resolved by the time filter handlers are added to the chain in the next step (e.g. the attributes are set if any).

接下来,modperl hook_post_config调用modperl mgv_hash_handlers它通过DCFG工作-> handlers_per_dir[idx]解决了处理程序(通过modperl_mgv_resolve),所以他们解决的时间滤波器处理程序添加到链在下一步中(例如,如果有设置的属性)。

3. Now all is left is to add the filters to the appropriate chains at the appropriate time.

modperl_register_hooks() adds a pre_connection hook modperl_hook_pre_connection() which inserts connection filters via:

现在剩下的就是在适当的时候把过滤器添加到适当的连锁店。通过modperl_register_hooks()添加一个pre_connection插入modperl_hook_pre_connection()连接过滤器:

modperl_input_filter_add_connection();
modperl_output_filter_add_connection();
modperl_hook_pre_connection() is called during the pre_connection phase.
modperl_register_hooks() directly registers the request filters via ap_hook_insert_filter():
modperl_output_filter_add_request
modperl_input_filter_add_request

functions registered with ap_hook_insert_filter(), will be called when the request record is created and they are supposed to insert request filters if any. 函数注册ap_hook_insert_filter(),将被称为创建请求记录时他们应该插入请求过滤器。

All four functions perform a similar thing: loop through dcfg->handlers_per_dir[idx], where idx is per filter type: MP_{INPUT|OUTPUT}_FILTER_HANDLER, pick the filters of the appropriate type and insert them to filter chain using one of the two Apache functions that add filters. Since we have connection and request filters there are four different combinations:

所有四个函数执行类似的事情:循环dcfg-> handlers_per_dir idx每个过滤器类型的位置:MP_输入输出| } { _FILTER_HANDLER,选择适当的过滤器类型并使用Apache的两个函数插入过滤器链。既然我们有链接,并要求过滤器有四种不同的组合:

ap_add_input_filter( name, (void*)ctx, NULL, c);
ap_add_output_filter(name, (void*)ctx, NULL, c);
ap_add_input_filter( name, (void*)ctx, r, r->connection);
ap_add_output_filter(name, (void*)ctx, r, r->connection);
Here the name is one of: 这里的名称是:
MODPERL_REQUEST_OUTPUT
MODPERL_REQUEST_INPUT
MODPERL_CONNECTION_OUTPUT
MODPERL_CONNECTION_INPUT
ctx, storing three things: CTX,储存三件事情:
SV *data;
modperl_handler_t *handler;
PerlInterpreter *perl;

we have mentioned ctx->handler already, that’s where the real Perl filter handler is stored. ctx->perl stores the current perl interpreter (used only in the threaded environment). 我们已经提到ctx->处理程序,那才是真正的Perl过滤器处理程序存储。ctx->perl存储当前的perl解释器(只有在使用线程的环境)。

the last two arguments are the request and connection records.最后两个参数是请求和连接记录。

notice that dcfg->handlers_per_dir[idx] stores connection and request filters in the same array, so we have only two arrays, one for input and one for output filters. We know to distinguish between connection and request filters by looking at ctx->handler->attrs record, which is derived from the handler subroutine’s attributes. Remember that we can have: 注意dcfg-> handlers_per_dir idx商店连接和请求过滤器在同一个数组,所以我们只有两个数组,一个输入和一个输出过滤器。我们知道区分连接和请求过滤器通过观察ctx->处理程序- > attrs记录,这是来自处理程序子例程的属性。记住,我们可以:
sub Foo : FilterRequestHandler {}
and:
sub Bar : FilterConnectionHandler {}

For example we can figure out what kind of handler is that via: 我们可以通过例子找出什么样的处理程序:
if (ctx->handler->attrs & MP_FILTER_CONNECTION_HANDLER)) {
/* Connection handler */
}
else if (ctx->handler->attrs & MP_FILTER_REQUEST_HANDLER)) {
/* Request handler */
}
else {
/* Unknown */
}

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内