入口函數main位於 src/core/nginx.c
調用ngx_single_process_cycle來初始化socket模型
ngx_single_process_cycle位於src/os/win32/ngx_process_cycle.c
代碼如下:
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);
}
其中關鍵是調用init_process,init_process是struct ngx_module_s裡面的一個成員。
ngx_module_s定義如下:
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;
};
init_process作為指標指向的實際上是函數static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);該函數位於 src/event/ngx_event.c。
這裡對socket模型進行初始化
if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
/* fatal */
exit(2);
}
init也是一個函數指標,實際調用的是static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer),它位於src/event/modules/ngx_iocp_module.c裡面。
詳細代碼如下
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 could 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;
}
首先調用CreateIoCompletionPort建立IOCP對象,然後調用ngx_create_thread建立多個線程,並納入到IOCP的線程池中。