nginx epoll 事件模型
nginx做为一个异步高效的事件驱动型web服务器,在linux平台中当系统支持epoll时nginx默认采用epoll来高效的处理事件。nginx中使用ngx_event_t结构来表示一个事件,先介绍下ngx_event_t结构体中成员的含义:
struct ngx_event_s {
void *data; //与事件关联的对象,常指向事件所在的ngx_connection_t连接对象
unsigned write:1; //可写标识位,1表示对应的tcp连接是可写的
unsigned accept:1;// 1表示对应的连接是处于监听状态的连接,即可接收新的连接
/* used to detect the stale events in kqueue, rtsig, and epoll */
unsigned instance:1; //可来区分事件是否已过期
/*
* the event was passed or would be passed to a kernel;
* in aio mode - operation was posted.
*/
unsigned active:1;// 1表示事件活跃,即事件已添加到epoll中
unsigned disabled:1;//epoll中不使用该标识位
/* the ready event; in aio mode 0 means that no operation can be posted */
unsigned ready:1; //事件已就绪(即可读或可写)
unsigned oneshot:1;//epoll不使用该标识位
/* aio operation is complete */
unsigned complete:1;//aio中使用,表示 事件对应的aio异步操作已完成(io_getevents函数已成功返回)
unsigned eof:1;// 1表示当前处理的字符流已完成,如调用recv读取连接数据时返回0,此时置该标识位为1
unsigned error:1;// 1表示事件处理过程中发生错误
unsigned timedout:1; //事件是否超时,1:表示超时。超时后事件对应的请求不需再被处理(对于http模块来说事件超时后直接关闭请求)
unsigned timer_set:1; //为1时表示这个事件在定时器中
unsigned delayed:1;// 1表示 需延迟处理该事件,常用于限速功能中
unsigned deferred_accept:1;//延迟接收接连,即当连接中收到对象发送的数据后才真正建立连接
/* the pending eof reported by kqueue, epoll or in aio chain operation */
unsigned pending_eof:1;// 1表示TCP连接对向关闭读端,即epoll返回EPOLLRDHUP
#if !(NGX_THREADS)
unsigned posted_ready:1;//该标识位在1.5.5版本源码中只在ngx_epoll_process_events函数中有置位,其它地方并没有用到
#endif
#if (NGX_WIN32)
/* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
unsigned accept_context_updated:1;
#endif
#if (NGX_HAVE_KQUEUE)
unsigned kq_vnode:1;
/* the pending errno reported by kqueue */
int kq_errno;
#endif
/*
* kqueue only:
* accept: number of sockets that wait to be accepted
* read: bytes to read when event is ready
* or lowat when event is set with NGX_LOWAT_EVENT flag
* write: available space in buffer when event is ready
* or lowat when event is set with NGX_LOWAT_EVENT flag
*
* iocp: TODO
*
* otherwise:
* accept: 1 if accept many, 0 otherwise
*/
#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
int available;
#else
unsigned available:1;// 1表示每次调用accept时尽可能多的接收TCP连接,与multi_accept配置项对应
#endif
ngx_event_handler_pt handler; // 事件产生后的回调函数句柄
#if (NGX_HAVE_AIO)
#if (NGX_HAVE_IOCP)
ngx_event_ovlp_t ovlp;
#else
struct aiocb aiocb;
#endif
#endif
ngx_uint_t index; //epoll中不使用
ngx_log_t *log; //ngx_log_t对象
ngx_rbtree_node_t timer;
unsigned closed:1; // 1表示事件已关闭
/* to test on worker exit */
unsigned channel:1;// 只在ngx_add_channel_event函数中有置位,其它地方没用到
unsigned resolver:1; // resolver功能中使用?
#if (NGX_THREADS)
unsigned locked:1;
unsigned posted_ready:1;
unsigned posted_timedout:1;
unsigned posted_eof:1;
#if (NGX_HAVE_KQUEUE)
/* the pending errno reported by kqueue */
int posted_errno;
#endif
#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
int posted_available;
#else
unsigned posted_available:1;
#endif
ngx_atomic_t *lock;
ngx_atomic_t *own_lock;
#endif
/* the links of the posted queue */
ngx_event_t *next;
ngx_event_t **prev;
#if 0