The main entry function is located in src/CORE/nginx. C.
Call ngx_single_process_cycle to initialize the socket model
Ngx_single_process_cycle is located in src/OS/Win32/ngx_process_cycle.c
CodeAs follows:
Void
Ngx_single_process_cycle (ngx_cycle_t * cycle)
{
Ngx_int_t I;
Ngx_tid_t tid;
For (I = 0; ngx_modules [I]; I ++ ){
If (ngx_modules [I]-> init_process ){
If (ngx_modules [I]-> init_process (cycle) = ngx_error ){
/* Fatal */
Exit (2 );
}
}
}
Ngx_process_init (cycle );
Ngx_console_init (cycle );
If (ngx_create_signal_events (cycle )! = Ngx_ OK ){
Exit (2 );
}
If (ngx_create_thread (& tid, ngx_worker_thread, null, cycle-> log )! = 0 ){
/* Fatal */
Exit (2 );
}
/* Stub */
Waitforsingleobject (ngx_stop_event, infinite );
}
The key is to call init_process, which is a member of struct ngx_module_s.
Ngx_module_s is defined as follows:
Struct ngx_module_s {
Ngx_uint_t ctx_index;
Ngx_uint_t index;
Ngx_uint_t spare0;
Ngx_uint_t spare1;
Ngx_uint_t spare2;
Ngx_uint_t spare3;
Ngx_uint_t version;
Void * CTX;
Ngx_command_t * commands;
Ngx_uint_t type;
Ngx_int_t (* init_master) (ngx_log_t * log );
Ngx_int_t (* init_module) (ngx_cycle_t * cycle );
Ngx_int_t (* init_process) (ngx_cycle_t * cycle );
Ngx_int_t (* init_thread) (ngx_cycle_t * cycle );
Void (* exit_thread) (ngx_cycle_t * cycle );
Void (* exit_process) (ngx_cycle_t * cycle );
Void (* exit_master) (ngx_cycle_t * cycle );
Uintptr_t spare_hook0;
Uintptr_t spare_hook1;
Uintptr_t spare_hook2;
Uintptr_t spare_hook3;
Uintptr_t spare_hook4;
Uintptr_t spare_hook5;
Uintptr_t spare_hook6;
Uintptr_t spare_hook7;
};
As a pointer, init_process actually points to the static ngx_int_t ngx_event_process_init (ngx_cycle_t * cycle) function. This function is located in src/event/ngx_event.c.
The socket model is initialized here.
If (module-> actions. INIT (cycle, ngx_timer_resolution )! = Ngx_ OK ){
/* Fatal */
Exit (2 );
}
Init is also a function pointer. It actually calls static ngx_int_t ngx_iocp_init (ngx_cycle_t * cycle, ngx_msec_t timer), which is located in src/event/modules/ngx_iocp_module.c.
The Code is as follows:
Static ngx_int_t
Ngx_iocp_init (ngx_cycle_t * cycle, ngx_msec_t timer)
{
Ngx_iocp_conf_t * Cf;
Cf = ngx_event_get_conf (cycle-> conf_ctx, ngx_iocp_module );
If (iocp = NULL ){
Iocp = createiocompletionport (invalid_handle_value, null, 0,
CF-> threads );
}
If (iocp = NULL ){
Ngx_log_error (ngx_log_alert, cycle-> log, ngx_errno,
"Createiocompletionport () failed ");
Return ngx_error;
}
Ngx_io = ngx_iocp_io;
Ngx_event_actions = ngx_iocp_module_ctx.actions;
Ngx_event_flags = ngx_use_aio_event | ngx_use_iocp_event;
If (timer = 0 ){
Return ngx_ OK;
}
/*
* The waitable timer cocould not be used, because
* Getqueuedcompletionstatus () does not set a thread to alertable state
*/
If (timer_thread = NULL ){
MSEC = timer;
If (ngx_create_thread (& timer_thread, ngx_iocp_timer, & msec, cycle-> log)
! = 0)
{
Return ngx_error;
}
}
Ngx_event_flags | = ngx_use_timer_event;
Return ngx_ OK;
}
First, call createiocompletionport to create the iocp object, then call ngx_create_thread to create multiple threads, and include them in the iocp thread pool.