Home  >  Article  >  Backend Development  >  nginx source code (4) main process

nginx source code (4) main process

WBOY
WBOYOriginal
2016-08-08 09:27:59907browse

Continued from above.

nginx runs on the console as a single process. Read the main method in core/nginx.c. The preceding code is all initialization code. If you don’t read it carefully, you will easily fall into the devil’s ring. Directly find the definition of ngx_single_process_cycle, in os/unix/ngx_process_cycle.c.

Add the following code in the first for loop:

<code><span>for</span> (i = <span>0</span>; ngx_modules[i]; i++) {
        <span>char</span> * p = NULL;
        <span>if</span> (ngx_modules[i]->commands != NULL)
        {
            p = ngx_modules[i]->commands->name.data;
        }
        <span>if</span> (ngx_modules[i]->init_process) {
            <span>if</span> (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
                <span>/* fatal */</span><span>exit</span>(<span>2</span>);
            }
            <span>printf</span>(<span>"[ngx_process_cycle] module ctx_index=%d index=%d name=%s init process\n"</span>, ngx_modules[i]->ctx_index, ngx_modules[i]->index, p);
        }
        <span>else</span>
        {
            <span>printf</span>(<span>"[ngx_process_cycle] module ctx_index=%d index=%d name=%s\n"</span>, ngx_modules[i]->ctx_index, ngx_modules[i]->index, p);
        }
    }
    <span>printf</span>(<span>"[ngx_process_cycle] for ngx_modules init done\n"</span>);</code>

The function is to print which modules and related indexes and names are currently in nginx.

In the second for loop, it is mainly the ngx_process_events method. After searching, we found that this is a macro, and then this macro is a global variable. Because we loaded the epoll module, it is in event/modules/ngx_epoll_module.c
Found the code in:

<code>ngx_event_actions = ngx_epoll_module_ctx.actions;</code>

Found that the ngx_process_events method is actually the ngx_epoll_process_events method in the actions in the ngx_epoll_module_ctx module. Find the place where the epoll_wait method is called in this method, and add the following code:

<code><span>printf</span>(<span>"[ngx_epoll_module] epoll wait\n"</span>);
    events = epoll_wait(ep, event_list, nevents, timer);
    <span>printf</span>(<span>"[ngx_epoll_module] epoll wait ---\n"</span>);</code>

Remake running results:

[main] to start ngx_single_process_cycle
[ngx_process_cycle] module ctx_index=0 index=0 name=daemon
[ngx_process_cycle] module ctx_index=0 index=1 name=error_log
[ngx_process_cycle] module ctx_index=0 index=2 name=include
[ngx_process_cycle] module ctx_index=0 index=3 name=events
[ngx_process_cycle] module ctx_index=0 index=4 name=connections init process
[ngx_process_cycle] module ctx_index=1 index=5 name=rtsig_signo
[ngx_process_cycle] module ctx_index=2 index=6 name=epoll_events
[ngx_process_cycle] module ctx_index=0 index=7 name=http
[ngx_process_cycle] module ctx_index=0 index=8 name=server
[ngx_process_cycle] module ctx_index=1 index=9 name=log_format
[ngx_process_cycle] module ctx_index=2 index=10 name=(null)
[ngx_process_cycle] module ctx_index=3 index=11 name=index
[ngx_process_cycle] module ctx_index=4 index=12 name=allow
[ngx_process_cycle] module ctx_index=5 index=13 name=rewrite
[ngx_process_cycle] module ctx_index=6 index=14 name=proxy_pass
[ngx_process_cycle] module ctx_index=7 index=15 name=(null)
[ngx_process_cycle] module ctx_index=8 index=16 name=(null)
[ngx_process_cycle] module ctx_index=9 index=17 name=(null)
[ngx_process_cycle] module ctx_index=10 index=18 name=(null)
[ngx_process_cycle] module ctx_index=11 index=19 name=gzip
[ngx_process_cycle] module ctx_index=12 index=20 name=charset_map
[ngx_process_cycle] module ctx_index=13 index=21 name=userid
[ngx_process_cycle] module ctx_index=14 index=22 name=expires
[ngx_process_cycle] module ctx_index=15 index=23 name=output_buffers
[ngx_process_cycle] module ctx_index=16 index=24 name=(null)
[ngx_process_cycle] module ctx_index=17 index=25 name=(null)
[ngx_process_cycle] for ngx_modules init done
[ngx_epoll_module] epoll wait
^C[ngx_epoll_module] epoll wait —

Found a total of 25 modules, only the connections module has the init_process method, and some module names are empty. Finally, the program enters the epoll module and is blocked at the epoll_wait call. The subsequent print statement is executed only after CTRL+C is launched.

Here you can take a closer look at nginx’s definition of modules. When looking at the code, it is easy to find that the actual types used in nginx all end with _t. If this type is defined as a structure, the actual types end with _s. , nginx_module_s is defined in the core/ngx_conf_file.h file:

<code><span>struct</span> ngx_module_s {
    ngx_uint_t       ctx_index;
    ngx_uint_t       index;
    <span>void</span>            *ctx;
    ngx_command_t   *commands;
    ngx_uint_t       type;
    ngx_int_t      (*init_module)(ngx_cycle_t *cycle);
    ngx_int_t      (*init_process)(ngx_cycle_t *cycle);
<span>#if 0</span>
    ngx_int_t      (*init_thread)(ngx_cycle_t *cycle);
<span>#endif</span>
};</code>

There are two index numbers, as well as commands and 3 functions. The specific meaning will be used later.

There are two other structures ngx_event_module_t and ngx_event_actions_t; the latter is a member of the former; the former is the nginx event module, but it is abstract and will have different types on a certain platform, here it is epoll.
ngx_event_module_t is as follows:

<code>typedef struct {
    ngx_str_t              <span>*name</span>;

    void                 <span>*(</span><span>*create_conf</span>)(ngx_cycle_t <span>*cycle</span>);
    char                 <span>*(</span><span>*init_conf</span>)(ngx_cycle_t <span>*cycle</span>, void <span>*conf</span>);

    ngx_event_actions_t     actions;
} ngx_event_module_t;</code>

epoll instance is as follows:

<code>ngx_event_module_t  ngx_epoll_module_ctx = {
    &epoll_name,
    ngx_epoll_create_conf,               <span>/* create configuration */</span>
    ngx_epoll_init_conf,                 <span>/* init configuration */</span>    {
        ngx_epoll_add_event,             <span>/* add an event */</span>
        ngx_epoll_del_event,             <span>/* delete an event */</span>
        ngx_epoll_add_event,             <span>/* enable an event */</span>
        ngx_epoll_del_event,             <span>/* disable an event */</span>
        ngx_epoll_add_connection,        <span>/* add an connection */</span>
        ngx_epoll_del_connection,        <span>/* delete an connection */</span><span>NULL</span>,                            <span>/* process the changes */</span>
        ngx_epoll_process_events,        <span>/* process the events */</span>
        ngx_epoll_init,                  <span>/* init the events */</span>
        ngx_epoll_done,                  <span>/* done the events */</span>
    }
};</code>

It happens that the actions members in ngx_event_module_t are defined in ngx_epoll_module_ctx as some functions related to epoll, and the previous ngx_process_events are concatenated by the following two lines of code:
In event/ngx_event.h

<code><span>#<span>define</span> ngx_process_events   ngx_event_actions.process_events</span></code>

event/modules/ngx_epoll_module.c

<code><span>   ngx_event_actions </span>=<span> ngx_epoll_module_ctx.actions;</span></code>

ngx_event_actions is defined as a global variable in event/ngx_event.c:

<code>ngx_event_actions_t               ngx_event_actions;</code>

Next, let’s take a look at the use of epoll in nginx.

to be continued …

The above introduces the main process of nginx source code (4), including various aspects. I hope it will be helpful to friends who are interested in PHP tutorials.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn