


nginx source code study notes (20) - event module 1 - initialization
After reading the previous study notes, I believe that I have a certain understanding of the startup process of nginx. From this section on, we want to go deep into each module and learn the main operations within each module.
This article comes from: http://blog.csdn.net/lengzijian/article/details/7598996
Today we will learn about the event module. In the previous startup, we mentioned calling each module many times. The hook function of
This method mainly creates an ngx_event_conf_t structure and allocates memory space.
For example, the read file has the following lines:
[cpp] view
plaincopyprint?
events
{
use epoll;
- worker_connections 10240; }
- The events in this place are a block instruction. Many instructions can be configured within the brackets. These instructions are defined in src/event/ngx_event.c
- [cpp] view plaincopyprint?
ngx_command_t ngx_event_core_commands[] = {
{ ngx_string(
- "worker_ connections"
- ), NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_connections,
- 0, 0,
- NULL },
- ...(omitted here)
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_connections,
- 0,
- 0, NULL },
- {ngx_string(
- "use" ),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_use,
- 0,
- 0, NULL },
- ngx_null_command
- };
- When events are parsed, the following function will be called back:
- [cpp] view plaincopyprint?
-
- src/event/ngx_event.c
- static char *
- ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
- {
- char *rv;
- void ***ctx;
- ngx_uint_t i;
- ngx_conf_t pcf;
- ngx_event_module_t *m;
- /* count the number of the event modules and set up their indices */
- //计算event模块数量,并且记录
- ngx_event_max_module = 0;
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- continue;
- }
- ngx_modules[i]->ctx_index = ngx_event_max_module++;
- }
- ctx = ngx_pcalloc(cf->pool, sizeof(void *));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
- //为每一个event模块分配空间,用来保存响应配置结构的地址
- //共分配了ngx_event_max_module个空间
- *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
- if (*ctx == NULL) {
- return NGX_CONF_ERROR;
- }
- *(void **) conf = ctx;
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- continue;
- }
- m = ngx_modules[i]->ctx;
- if
- (m->create_conf) { (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
- ((*ctx)[ngx_modules[i]->ctx_index] == NULL) {
- pcf = *cf; cf->ctx = ctx;
- cf->module_type = NGX_EVENT_MODULE;
- cf->cmd_type = NGX_EVENT_CONF;
- //Since events is a block instruction, many other instructions can be configured in the events domain,
- //For example, the use mentioned before, etc., now start to parse the instructions in the events block and complete the initialization Work.
- rv = ngx_conf_parse(cf, NULL);
- *cf = pcf;
- if (rv != NGX_CONF_OK)
-
- if(ngx_modules[i]-> ;type != NGX_EVENT_MODULE) {
- m = ngx_modules[i]->ctx;
- //Loop to execute each event The init_conf function of the module, the initialization configuration structure
- (m-& gt; init_conf) {
- RV = m-& gt; init_conf (CF-& GT; cycle, (*ctx) [ngx_modules[i]->ctx_index]); return
- rv;
- }
- return NGX_CONF_OK;
- }
The most important process in the ngx_events_block() function is to call ngx_conf_parse(cf, NULL). The function of calling ngx_conf_parse() here is to complete the parsing of the events{} block in the configuration file, thereby calling all configurations under it. The callback function of the instruction completes the initialization of parsing the configuration file. But here I have a personal question. After asking the seniors, I will specify the question and answer******.
2. Initialize conf (init_conf)
ngx_event_init_conf()
This method mainly initializes the ngx_event_conf_t structure.
3.ngx_event_module_init
As the name suggests, it is the initialization operation of the module, but looking at the source code of each module, it is found that many modules do not have init callback functions. I am also struggling with why here, hoping to find the answer after learning all the code.
[cpp] view plaincopyprint?
- src/event/ngx_event.c
- static ngx_int_t
- ngx_event_module_init(ngx_cycle_t *cycle)
- {
- void ***cf;
- u_char *shared;
- size_t size, cl;
- ngx_shm_t shm;
- ngx_time_t *tp;
- ngx_core_conf_t *ccf;
- ngx_event_conf_t *ecf;
- //判断ngx_events_module是否调用过初始化conf操作
- cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
- if (cf == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "no "events" section in configuration");
- return NGX_ERROR;
- }
- //获取ngx_event_core_module模块的配置结构
- ecf = (*cf)[ngx_event_core_module.ctx_index];
- //查看是否是event中的模块,例如use 。。。。
- if (!ngx_test_config && ngx_process
- ngx_log_error(NGX _LOG_NOTICE, cycle->log, 0,
- "event method", ecf->name);
- }
- //Get the configuration structure of the ngx_core_module module
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle- >conf_ctx, ngx_core_module);
- //Get the timer_resolution parameter from the configuration structure of the ngx_core_module module ngx_timer_resolution = ccf->timer_resolution;
- #if !(NGX_WIN32)
- { ngx_int_t limit;
- rlimit rlmt;
- //Get the ability of the current process The maximum number of open files man getrlimit
- (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { x_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- else{
- _The maximum number of connections to a module is unlimited
- / /Or ngx_event_core_module connection is greater than ngx_core_module maximum number of connections
- (ECF-& GT; Connections & GT; (ngx_uint_t) rlmt.rlim_cur
- (ccf-& gt; _NOFILE == ngx_conf_unset limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ?
- ( ngx_int_t) rlmt.rlim_cur: ccf- & gt; rlimit_nofile;
- " open file resource limit: %i" ); endif /* !(NGX_WIN32) */
- //If the master process is closed, return
- //Because closing the master process means single-process work Method,
- //The subsequent operations create shared memory to implement locks and other work, which is not required for a single process.
- if (ccf->master == 0) {
- NGX_OK; }
- // If the accept mutex already exists, there is no need to create it again.
- NGX_OK;
- }
- /* cl should be equal or bigger than cache line size */
- cl = 128;
- //Create size here Shared memory, this shared memory will be divided into three equal segments
- size = cl + cl
- ,
- shm.size = size;
- shm.name.len = sizeof("nginx_shared_zone" );
- shm.name.data = (u_char *) "nginx_share d_zone" ;
- shm.log = cycle->log;
- (ngx_shm_alloc(&shm) ! = NGX_OK) { NGX_ERROR;
- NGX_ERROR;
- shared = shm.addr;
- //Accept mutex gets the first cl size memory of shared memory
- ngx_accept_mutex_ptr = (ngx_atomic_t *) shared; ngx_accept_mutex.spin = (ngx_uint_t) -1;
- /*Create accept mutex
- The implementation of accept mutex depends on whether it supports atomic operations, if there are corresponding atomic operations;
- That’s it Use the obtained shared memory to implement the accept mutex; otherwise, the file lock will be used to implement the accept mutex.
- The function of the accept mutex is to avoid panic groups and achieve load balancing of worker processes.
- ngx_accept_mutex, shared, cycle->lock_file.data) != NGX_OK)
- //Get the cl-sized address of the second segment of memory
- ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
- ( void
- ) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle- >log, 0,
- x_connection_counter); //Get the size of the third segment of memory cl Address
- ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);
- tp = ngx_timeofday() ;
- ngx_random_number = (tp-> ;msec
- return
- NGX_OK;
- 4.ngx_event_process_init in the previous worker process As mentioned in the analysis, when a worker process is created, the worker process will first initialize the process, and at this time the ngx_event_process_init function will be called.
- [cpp] view plaincopyprint?
- src/event/ngx_event.c
- staticngx_int_t
- ngx_event_process_init(ngx_cycle_t *cycle)
- {
- ngx_uint_t m, i;
- ngx_event_t *rev, *wev;
- ngx_listening_t *ls;
- ngx_connection_t *c, *next, *old;
- ngx_core_conf_t *ccf;
- ngx_event_conf_t *ecf;
- ngx_event_module_t *module;
- //As before, get the configuration structure of the response module
- ccf = (ngx_core_conf_t *) ngx_get_conf( cycle->conf_ctx, ngx_core_module);
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
- //Master process is open, worker process is greater than 1, accept_mutex has been created
- //cai Open the accept mutex
- if (ccf->master &&ccf->worker_processes > 1 &&ecf->accept_mutex) {
- ngx_use_accept_mutex = 1; / /Use mutex
- ngx_accept_mutex_held = 0; //Whether to get accept mutex
- ngx_accept_mutex_delay = ecf->accept_mutex_delay;//After failure to compete for the mutex , waiting for the next scramble time interval
- } else {
- ngx_use_accept_mutex = 0 ;
- }
- #if (NGX_THREADS)
- //Threads aside
- #endif
- //Initialize counter, a red will be created here Black Tree, to maintain the timer, will explain in detail later
- if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
- return NGX_ERROR; }
- for (m = 0; ngx_modules[m]; m++) {
- //As mentioned here before, skip non-NGX_EVENT_MODULE modules
- }
- // Modules specified by non-use configuration instructions are skipped, Linux default epoll ->use) { module = ngx_modules[m]->ctx;
- /*Call the init function of the specific time module ( These modules are located in the src/event/modules directory), so nginx A layer of abstraction has been made to the time module, which makes it easier for different systems to use different event models and expands new time models. Our focus should be on epoll.
- The init callback here actually calls the ngx_epoll_init function. The module->actions structure encapsulates all interface functions of epoll. nginx registers epoll into the event abstraction layer through the actions structure. The type of actions is ngx_event_action_t, located in src/event/ngx_event.h
- These specific contents will be explained in the next section.
- module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
- *fatal */
- exit(2); break ;
- }
- //Omitted here Part of the content
- //Create a global ngx_connection_t array to save all connections
- //Since this process is executed in each worker process, each worker has Own connection array
- cycle->connections = ngx_alloc(sizeof (ngx_connection_t) *cycle->connection_n, cycle->log);
- if (cycle->connections == NULL) {
- c = cycle->connections;
- //Create an array of read events
- cycle->read_events = ngx_alloc(sizeof
- (ngx_event_t) * cycle->connection_n, ;log);
- if
- (cycle->read_events == NULL) {
- NGX_ERROR;
- }
- rev = cycle->read_events;
- for (i = 0; i connection_n; i++) {
- rev[i].closed = 1 ;
- [i].instance = 1; #if (NGX_THREADS)
- rev[i].lock = &c[i].lock;
- rev[i].own_lock = &c[i].lock;
- #endif
- }
- //创建一个写事件数组
- cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
- cycle->log);
- if (cycle->write_events == NULL) {
- return NGX_ERROR;
- }
- wev = cycle->write_events;
- for (i = 0; i connection_n; i++) {
- wev[i].closed = 1;
- #if (NGX_THREADS)
- wev[i].lock = &c[i].lock;
- wev[i].own_lock = &c[i].lock;
- #endif
- }
- i = cycle->connection_n;
- next = NULL;
- //初始化整个connection数组
- do {
- i--;
- c[i].data = next;
- c[i].read = &cycle->read_events[i];
- c[i].write = &cycle->write_events[i];
- c[i].fd = (ngx_socket_t) -1;
- next = &c[i];
- #if (NGX_THREADS)
- c[i].lock = 0;
- #endif
- }while (i);
- cycle->free_connections = next;
- cycle->free_connection_n = cycle-> connection_n;
- /* for each listening socket */
- //Assign a connection from the connection array for each listening socket, that is, a slot
- ls = cycle->listening .els; Connect to solt
- _ C = ngx_get_connection (ls [i] .fd, cycle-& gt; log); NGX_ERROR; }
- c->log = &ls[i].log;
- c->listening = &ls[i];
- ls[i].connection = c;
- rev = c->read;
- rev->log = c->log;
- rev->accept = 1; //读时间发生,调用accept
- #if (NGX_HAVE_DEFERRED_ACCEPT)
- //省略
- #endif
- if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
- if (ls[i].previous) {
- /*
- * delete the old accept events that were bound to
- * the old cycle read events array
- */
- old = ls[i].previous->connection;
- if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
- old->fd = (ngx_socket_t) -1;
- }
- }
- //Register the callback function ngx_event_accept
- rev->handler = ngx_even t_accept;
- , do not put the listening socket into epoll for the time being, but
- {
- }
- } else{
- //If the accept mutex is not used, then put this listening socket into epoll.
- #endif
- }
- return
- NGX_OK;
- }
- Until now , event-driven initialization has been completed. The above introduces the nginx source code study notes (20) - event module 1 - initialization, including IOC and counter content. I hope it will be helpful to friends who are interested in PHP tutorials.

APHPDependencyInjectionContainerisatoolthatmanagesclassdependencies,enhancingcodemodularity,testability,andmaintainability.Itactsasacentralhubforcreatingandinjectingdependencies,thusreducingtightcouplingandeasingunittesting.

Select DependencyInjection (DI) for large applications, ServiceLocator is suitable for small projects or prototypes. 1) DI improves the testability and modularity of the code through constructor injection. 2) ServiceLocator obtains services through center registration, which is convenient but may lead to an increase in code coupling.

PHPapplicationscanbeoptimizedforspeedandefficiencyby:1)enablingopcacheinphp.ini,2)usingpreparedstatementswithPDOfordatabasequeries,3)replacingloopswitharray_filterandarray_mapfordataprocessing,4)configuringNginxasareverseproxy,5)implementingcachingwi

PHPemailvalidationinvolvesthreesteps:1)Formatvalidationusingregularexpressionstochecktheemailformat;2)DNSvalidationtoensurethedomainhasavalidMXrecord;3)SMTPvalidation,themostthoroughmethod,whichchecksifthemailboxexistsbyconnectingtotheSMTPserver.Impl

TomakePHPapplicationsfaster,followthesesteps:1)UseOpcodeCachinglikeOPcachetostoreprecompiledscriptbytecode.2)MinimizeDatabaseQueriesbyusingquerycachingandefficientindexing.3)LeveragePHP7 Featuresforbettercodeefficiency.4)ImplementCachingStrategiessuc

ToimprovePHPapplicationspeed,followthesesteps:1)EnableopcodecachingwithAPCutoreducescriptexecutiontime.2)ImplementdatabasequerycachingusingPDOtominimizedatabasehits.3)UseHTTP/2tomultiplexrequestsandreduceconnectionoverhead.4)Limitsessionusagebyclosin

Dependency injection (DI) significantly improves the testability of PHP code by explicitly transitive dependencies. 1) DI decoupling classes and specific implementations make testing and maintenance more flexible. 2) Among the three types, the constructor injects explicit expression dependencies to keep the state consistent. 3) Use DI containers to manage complex dependencies to improve code quality and development efficiency.

DatabasequeryoptimizationinPHPinvolvesseveralstrategiestoenhanceperformance.1)Selectonlynecessarycolumnstoreducedatatransfer.2)Useindexingtospeedupdataretrieval.3)Implementquerycachingtostoreresultsoffrequentqueries.4)Utilizepreparedstatementsforeffi


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SublimeText3 Chinese version
Chinese version, very easy to use

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Dreamweaver Mac version
Visual web development tools
