Posted on 2011-09-30 09:45
冷鋒 閱讀(406)
評論(0) 編輯 收藏 引用 所屬分類:
linux
ngx_connection_t,抽象的連接,在core模塊的ngx_event_process_init 函數中預先分配好。ngx_event_process_init預分配connects,read\write 事件的數組,
并依次初始化,并依次初始化各連接的鏈表關系,也就是在data上存下一個connection的指針
cycle->connections =
ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
if (cycle->connections == NULL) {
return NGX_ERROR;
}
.
c = cycle->connections;
.
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;
//初始化linsten socket,并設置listen的處理函數為 rev->handler = ngx_event_acceptex;
Rev->accept=1;
for (i = 0; i < cycle->listening.nelts; i++) {
c = ngx_get_connection(ls[i].fd, cycle->log);
if (c == NULL) {
return NGX_ERROR;
}
}(結構體部分成員)
struct ngx_connection_s {
void *data;
ngx_event_t *read;//讀事件處理
ngx_event_t *write;//寫事件處理
ngx_socket_t fd;//連接對應的socket
ngx_listening_t *listening;/
ngx_log_t *log;
ngx_pool_t *pool;
//平臺相關的讀寫,對應socket的send,recv
ngx_recv_pt recv;
ngx_send_pt send;
struct sockaddr *sockaddr;//地址
socklen_t socklen;
ngx_str_t addr_text;
}
ngx_get_connection:從freeconnect隊頭取出一個connection,并將socket綁定此connection
在上層應用(比如HTTP),使用ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)加入讀事件。
在ngx_epoll_process_events函數中,
if (flags & NGX_POST_EVENTS) {
ngx_locked_post_event(wev, &ngx_posted_events);
} else {
wev->handler(wev);
}
如果帶有NGX_POST_EVENTS標記,就把事件投遞到隊列中不立即處理。
在ngx_process_events_and_timers 中,會在每個循環調用ngx_event_process_posted(cycle, &ngx_posted_events);不斷取出事件隊列進行處理。
NGX_POST_EVENTS是為了進行耗時操作前先釋放進程鎖,放入隊列稍后再處理(用進程鎖應該是避免N個進程accept導致的驚群,新版linux已經不會出現這個問題)。
if (ngx_posted_events) {
if (ngx_threaded) {
ngx_wakeup_worker_thread(cycle);
} else {
ngx_event_process_posted(cycle, &ngx_posted_events);
}
}