@@ -20,6 +20,9 @@ static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
20
20
static void ngx_close_accepted_connection (ngx_connection_t * c );
21
21
22
22
23
+ // 监听端口上收到连接请求时的回调函数,即事件handler
24
+ // 从cycle的连接池里获取连接
25
+ // 关键操作 ls->handler(c);调用其他模块的业务handler
23
26
void
24
27
ngx_event_accept (ngx_event_t * ev )
25
28
{
@@ -37,6 +40,7 @@ ngx_event_accept(ngx_event_t *ev)
37
40
static ngx_uint_t use_accept4 = 1 ;
38
41
#endif
39
42
43
+ // 事件已经超时
40
44
if (ev -> timedout ) {
41
45
// 遍历监听端口列表,加入epoll连接事件
42
46
if (ngx_enable_accept_events ((ngx_cycle_t * ) ngx_cycle ) != NGX_OK ) {
@@ -48,15 +52,22 @@ ngx_event_accept(ngx_event_t *ev)
48
52
49
53
ecf = ngx_event_get_conf (ngx_cycle -> conf_ctx , ngx_event_core_module );
50
54
55
+ // rtsig在nginx 1.9.x已经删除
51
56
if (ngx_event_flags & NGX_USE_RTSIG_EVENT ) {
52
57
ev -> available = 1 ;
53
58
54
59
} else if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT )) {
60
+ // epoll是否允许尽可能接受多个请求
55
61
ev -> available = ecf -> multi_accept ;
56
62
}
57
63
64
+ // 事件的连接对象
58
65
lc = ev -> data ;
66
+
67
+ // 事件对应的监听端口对象
59
68
ls = lc -> listening ;
69
+
70
+ // 此时还没有数据可读
60
71
ev -> ready = 0 ;
61
72
62
73
ngx_log_debug2 (NGX_LOG_DEBUG_EVENT , ev -> log , 0 ,
@@ -65,6 +76,7 @@ ngx_event_accept(ngx_event_t *ev)
65
76
do {
66
77
socklen = NGX_SOCKADDRLEN ;
67
78
79
+ // 调用accept接受连接,返回socket对象
68
80
#if (NGX_HAVE_ACCEPT4 )
69
81
if (use_accept4 ) {
70
82
s = accept4 (lc -> fd , (struct sockaddr * ) sa , & socklen ,
@@ -76,6 +88,7 @@ ngx_event_accept(ngx_event_t *ev)
76
88
s = accept (lc -> fd , (struct sockaddr * ) sa , & socklen );
77
89
#endif
78
90
91
+ // 接受连接出错
79
92
if (s == (ngx_socket_t ) - 1 ) {
80
93
err = ngx_socket_errno ;
81
94
@@ -117,6 +130,7 @@ ngx_event_accept(ngx_event_t *ev)
117
130
}
118
131
}
119
132
133
+ // 系统的文件句柄数用完了
120
134
if (err == NGX_EMFILE || err == NGX_ENFILE ) {
121
135
// 遍历监听端口列表,删除epoll监听连接事件,不接受请求
122
136
if (ngx_disable_accept_events ((ngx_cycle_t * ) ngx_cycle )
@@ -125,29 +139,36 @@ ngx_event_accept(ngx_event_t *ev)
125
139
return ;
126
140
}
127
141
142
+ // 解锁负载均衡,允许其他进程接受请求
128
143
if (ngx_use_accept_mutex ) {
129
144
if (ngx_accept_mutex_held ) {
130
145
ngx_shmtx_unlock (& ngx_accept_mutex );
131
146
ngx_accept_mutex_held = 0 ;
132
147
}
133
148
149
+ //未持有锁,暂时不接受请求
134
150
ngx_accept_disabled = 1 ;
135
151
136
152
} else {
153
+ // 不使用负载均衡
154
+ // 等待一下,再次尝试接受请求
137
155
ngx_add_timer (ev , ecf -> accept_mutex_delay );
138
156
}
139
157
}
140
158
141
159
return ;
142
- }
160
+ } // 接受连接出错
143
161
144
162
#if (NGX_STAT_STUB )
145
163
(void ) ngx_atomic_fetch_add (ngx_stat_accepted , 1 );
146
164
#endif
147
165
166
+ // ngx_accept_disabled是总连接数的1/8-空闲连接数
167
+ // 也就是说空闲连接数小于总数的1/8,那么就暂时停止接受连接
148
168
ngx_accept_disabled = ngx_cycle -> connection_n / 8
149
169
- ngx_cycle -> free_connection_n ;
150
170
171
+ // 从全局变量ngx_cycle里获取空闲链接,即free_connections链表
151
172
c = ngx_get_connection (s , ev -> log );
152
173
153
174
if (c == NULL ) {
@@ -163,12 +184,14 @@ ngx_event_accept(ngx_event_t *ev)
163
184
(void ) ngx_atomic_fetch_add (ngx_stat_active , 1 );
164
185
#endif
165
186
187
+ // 创建连接使用的内存池
166
188
c -> pool = ngx_create_pool (ls -> pool_size , ev -> log );
167
189
if (c -> pool == NULL ) {
168
190
ngx_close_accepted_connection (c );
169
191
return ;
170
192
}
171
193
194
+ // 拷贝客户端sockaddr
172
195
c -> sockaddr = ngx_palloc (c -> pool , socklen );
173
196
if (c -> sockaddr == NULL ) {
174
197
ngx_close_accepted_connection (c );
@@ -185,6 +208,7 @@ ngx_event_accept(ngx_event_t *ev)
185
208
186
209
/* set a blocking mode for aio and non-blocking mode for others */
187
210
211
+ // 设置socket为非阻塞
188
212
if (ngx_inherited_nonblocking ) {
189
213
if (ngx_event_flags & NGX_USE_AIO_EVENT ) {
190
214
if (ngx_blocking (s ) == -1 ) {
@@ -208,6 +232,10 @@ ngx_event_accept(ngx_event_t *ev)
208
232
209
233
* log = ls -> log ;
210
234
235
+ // 连接的收发数据函数
236
+ // #define ngx_recv ngx_io.recv
237
+ // #define ngx_recv_chain ngx_io.recv_chain
238
+ // ngx_posix_init.c里初始化为linux的底层接口
211
239
c -> recv = ngx_recv ;
212
240
c -> send = ngx_send ;
213
241
c -> recv_chain = ngx_recv_chain ;
@@ -216,6 +244,7 @@ ngx_event_accept(ngx_event_t *ev)
216
244
c -> log = log ;
217
245
c -> pool -> log = log ;
218
246
247
+ // 设置其他的成员
219
248
c -> socklen = socklen ;
220
249
c -> listening = ls ;
221
250
c -> local_sockaddr = ls -> sockaddr ;
@@ -234,11 +263,14 @@ ngx_event_accept(ngx_event_t *ev)
234
263
}
235
264
#endif
236
265
266
+ // 连接相关的读写事件
237
267
rev = c -> read ;
238
268
wev = c -> write ;
239
269
270
+ // 建立连接后是可写的
240
271
wev -> ready = 1 ;
241
272
273
+ // rtsig在nginx 1.9.x已经删除
242
274
if (ngx_event_flags & (NGX_USE_AIO_EVENT |NGX_USE_RTSIG_EVENT )) {
243
275
/* rtsig, aio, iocp */
244
276
rev -> ready = 1 ;
@@ -263,6 +295,7 @@ ngx_event_accept(ngx_event_t *ev)
263
295
* or protection by critical section or light mutex
264
296
*/
265
297
298
+ // 连接计数器增加
266
299
c -> number = ngx_atomic_fetch_add (ngx_connection_counter , 1 );
267
300
268
301
#if (NGX_STAT_STUB )
@@ -364,12 +397,18 @@ ngx_event_accept(ngx_event_t *ev)
364
397
log -> data = NULL ;
365
398
log -> handler = NULL ;
366
399
400
+ // 接受连接,收到请求的回调函数
401
+ // 在http模块里是http.c:ngx_http_init_connection
367
402
ls -> handler (c );
368
403
404
+ // epoll不处理
369
405
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT ) {
370
406
ev -> available -- ;
371
407
}
372
408
409
+ // 如果ev->available = ecf->multi_accept;
410
+ // epoll尽可能接受多个请求
411
+ // 否则epoll只接受一个请求后即退出循环
373
412
} while (ev -> available );
374
413
}
375
414
0 commit comments