0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
660
|
4 * Copyright (C) Nginx, Inc.
|
0
|
5 */
|
|
6
|
|
7
|
|
8 #include <ngx_config.h>
|
|
9 #include <ngx_core.h>
|
|
10 #include <ngx_event.h>
|
|
11
|
|
12
|
|
13 #define DEFAULT_CONNECTIONS 512
|
|
14
|
|
15
|
16
|
16 extern ngx_module_t ngx_kqueue_module;
|
236
|
17 extern ngx_module_t ngx_eventport_module;
|
16
|
18 extern ngx_module_t ngx_devpoll_module;
|
|
19 extern ngx_module_t ngx_epoll_module;
|
|
20 extern ngx_module_t ngx_rtsig_module;
|
0
|
21 extern ngx_module_t ngx_select_module;
|
|
22
|
|
23
|
672
|
24 static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
|
0
|
25 static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle);
|
|
26 static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
|
|
27 static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
|
28
|
|
29 static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
|
58
|
30 void *conf);
|
0
|
31 static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
|
32 static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
|
58
|
33 void *conf);
|
0
|
34
|
672
|
35 static void *ngx_event_core_create_conf(ngx_cycle_t *cycle);
|
|
36 static char *ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf);
|
0
|
37
|
|
38
|
112
|
39 static ngx_uint_t ngx_timer_resolution;
|
|
40 sig_atomic_t ngx_event_timer_alarm;
|
|
41
|
44
|
42 static ngx_uint_t ngx_event_max_module;
|
0
|
43
|
44
|
44 ngx_uint_t ngx_event_flags;
|
|
45 ngx_event_actions_t ngx_event_actions;
|
0
|
46
|
|
47
|
516
|
48 static ngx_atomic_t connection_counter = 1;
|
42
|
49 ngx_atomic_t *ngx_connection_counter = &connection_counter;
|
0
|
50
|
|
51
|
42
|
52 ngx_atomic_t *ngx_accept_mutex_ptr;
|
160
|
53 ngx_shmtx_t ngx_accept_mutex;
|
|
54 ngx_uint_t ngx_use_accept_mutex;
|
236
|
55 ngx_uint_t ngx_accept_events;
|
44
|
56 ngx_uint_t ngx_accept_mutex_held;
|
|
57 ngx_msec_t ngx_accept_mutex_delay;
|
|
58 ngx_int_t ngx_accept_disabled;
|
110
|
59 ngx_file_t ngx_accept_mutex_lock_file;
|
0
|
60
|
|
61
|
|
62 #if (NGX_STAT_STUB)
|
|
63
|
|
64 ngx_atomic_t ngx_stat_accepted0;
|
|
65 ngx_atomic_t *ngx_stat_accepted = &ngx_stat_accepted0;
|
44
|
66 ngx_atomic_t ngx_stat_handled0;
|
|
67 ngx_atomic_t *ngx_stat_handled = &ngx_stat_handled0;
|
0
|
68 ngx_atomic_t ngx_stat_requests0;
|
|
69 ngx_atomic_t *ngx_stat_requests = &ngx_stat_requests0;
|
|
70 ngx_atomic_t ngx_stat_active0;
|
|
71 ngx_atomic_t *ngx_stat_active = &ngx_stat_active0;
|
|
72 ngx_atomic_t ngx_stat_reading0;
|
|
73 ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0;
|
|
74 ngx_atomic_t ngx_stat_writing0;
|
44
|
75 ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0;
|
0
|
76
|
|
77 #endif
|
|
78
|
|
79
|
|
80
|
|
81 static ngx_command_t ngx_events_commands[] = {
|
|
82
|
|
83 { ngx_string("events"),
|
|
84 NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
|
85 ngx_events_block,
|
|
86 0,
|
|
87 0,
|
|
88 NULL },
|
|
89
|
|
90 ngx_null_command
|
|
91 };
|
|
92
|
126
|
93
|
0
|
94 static ngx_core_module_t ngx_events_module_ctx = {
|
|
95 ngx_string("events"),
|
|
96 NULL,
|
672
|
97 ngx_event_init_conf
|
126
|
98 };
|
0
|
99
|
|
100
|
|
101 ngx_module_t ngx_events_module = {
|
58
|
102 NGX_MODULE_V1,
|
0
|
103 &ngx_events_module_ctx, /* module context */
|
|
104 ngx_events_commands, /* module directives */
|
|
105 NGX_CORE_MODULE, /* module type */
|
90
|
106 NULL, /* init master */
|
0
|
107 NULL, /* init module */
|
90
|
108 NULL, /* init process */
|
|
109 NULL, /* init thread */
|
|
110 NULL, /* exit thread */
|
|
111 NULL, /* exit process */
|
|
112 NULL, /* exit master */
|
|
113 NGX_MODULE_V1_PADDING
|
0
|
114 };
|
|
115
|
|
116
|
|
117 static ngx_str_t event_core_name = ngx_string("event_core");
|
|
118
|
|
119
|
|
120 static ngx_command_t ngx_event_core_commands[] = {
|
|
121
|
92
|
122 { ngx_string("worker_connections"),
|
|
123 NGX_EVENT_CONF|NGX_CONF_TAKE1,
|
|
124 ngx_event_connections,
|
|
125 0,
|
|
126 0,
|
|
127 NULL },
|
|
128
|
0
|
129 { ngx_string("connections"),
|
|
130 NGX_EVENT_CONF|NGX_CONF_TAKE1,
|
|
131 ngx_event_connections,
|
|
132 0,
|
|
133 0,
|
|
134 NULL },
|
|
135
|
|
136 { ngx_string("use"),
|
|
137 NGX_EVENT_CONF|NGX_CONF_TAKE1,
|
|
138 ngx_event_use,
|
|
139 0,
|
|
140 0,
|
|
141 NULL },
|
|
142
|
|
143 { ngx_string("multi_accept"),
|
216
|
144 NGX_EVENT_CONF|NGX_CONF_FLAG,
|
0
|
145 ngx_conf_set_flag_slot,
|
|
146 0,
|
|
147 offsetof(ngx_event_conf_t, multi_accept),
|
|
148 NULL },
|
|
149
|
|
150 { ngx_string("accept_mutex"),
|
216
|
151 NGX_EVENT_CONF|NGX_CONF_FLAG,
|
0
|
152 ngx_conf_set_flag_slot,
|
|
153 0,
|
|
154 offsetof(ngx_event_conf_t, accept_mutex),
|
160
|
155 NULL },
|
0
|
156
|
|
157 { ngx_string("accept_mutex_delay"),
|
|
158 NGX_EVENT_CONF|NGX_CONF_TAKE1,
|
|
159 ngx_conf_set_msec_slot,
|
|
160 0,
|
|
161 offsetof(ngx_event_conf_t, accept_mutex_delay),
|
|
162 NULL },
|
|
163
|
|
164 { ngx_string("debug_connection"),
|
|
165 NGX_EVENT_CONF|NGX_CONF_TAKE1,
|
|
166 ngx_event_debug_connection,
|
|
167 0,
|
|
168 0,
|
|
169 NULL },
|
|
170
|
|
171 ngx_null_command
|
|
172 };
|
|
173
|
|
174
|
|
175 ngx_event_module_t ngx_event_core_module_ctx = {
|
|
176 &event_core_name,
|
672
|
177 ngx_event_core_create_conf, /* create configuration */
|
|
178 ngx_event_core_init_conf, /* init configuration */
|
0
|
179
|
|
180 { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
|
181 };
|
|
182
|
|
183
|
|
184 ngx_module_t ngx_event_core_module = {
|
58
|
185 NGX_MODULE_V1,
|
0
|
186 &ngx_event_core_module_ctx, /* module context */
|
|
187 ngx_event_core_commands, /* module directives */
|
|
188 NGX_EVENT_MODULE, /* module type */
|
90
|
189 NULL, /* init master */
|
0
|
190 ngx_event_module_init, /* init module */
|
90
|
191 ngx_event_process_init, /* init process */
|
|
192 NULL, /* init thread */
|
|
193 NULL, /* exit thread */
|
|
194 NULL, /* exit process */
|
|
195 NULL, /* exit master */
|
|
196 NGX_MODULE_V1_PADDING
|
0
|
197 };
|
|
198
|
|
199
|
112
|
200 void
|
|
201 ngx_process_events_and_timers(ngx_cycle_t *cycle)
|
|
202 {
|
|
203 ngx_uint_t flags;
|
116
|
204 ngx_msec_t timer, delta;
|
112
|
205
|
|
206 if (ngx_timer_resolution) {
|
|
207 timer = NGX_TIMER_INFINITE;
|
|
208 flags = 0;
|
|
209
|
|
210 } else {
|
|
211 timer = ngx_event_find_timer();
|
|
212 flags = NGX_UPDATE_TIME;
|
|
213
|
|
214 #if (NGX_THREADS)
|
|
215
|
|
216 if (timer == NGX_TIMER_INFINITE || timer > 500) {
|
|
217 timer = 500;
|
|
218 }
|
|
219
|
|
220 #endif
|
|
221 }
|
|
222
|
160
|
223 if (ngx_use_accept_mutex) {
|
112
|
224 if (ngx_accept_disabled > 0) {
|
|
225 ngx_accept_disabled--;
|
|
226
|
|
227 } else {
|
|
228 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
|
|
229 return;
|
|
230 }
|
|
231
|
|
232 if (ngx_accept_mutex_held) {
|
|
233 flags |= NGX_POST_EVENTS;
|
|
234
|
|
235 } else {
|
|
236 if (timer == NGX_TIMER_INFINITE
|
|
237 || timer > ngx_accept_mutex_delay)
|
|
238 {
|
|
239 timer = ngx_accept_mutex_delay;
|
|
240 }
|
|
241 }
|
|
242 }
|
|
243 }
|
|
244
|
116
|
245 delta = ngx_current_msec;
|
|
246
|
112
|
247 (void) ngx_process_events(cycle, timer, flags);
|
|
248
|
116
|
249 delta = ngx_current_msec - delta;
|
|
250
|
|
251 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
|
252 "timer delta: %M", delta);
|
|
253
|
112
|
254 if (ngx_posted_accept_events) {
|
|
255 ngx_event_process_posted(cycle, &ngx_posted_accept_events);
|
|
256 }
|
|
257
|
|
258 if (ngx_accept_mutex_held) {
|
160
|
259 ngx_shmtx_unlock(&ngx_accept_mutex);
|
112
|
260 }
|
|
261
|
122
|
262 if (delta) {
|
|
263 ngx_event_expire_timers();
|
|
264 }
|
|
265
|
112
|
266 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
|
267 "posted events %p", ngx_posted_events);
|
|
268
|
|
269 if (ngx_posted_events) {
|
|
270 if (ngx_threaded) {
|
|
271 ngx_wakeup_worker_thread(cycle);
|
|
272
|
|
273 } else {
|
|
274 ngx_event_process_posted(cycle, &ngx_posted_events);
|
|
275 }
|
|
276 }
|
|
277 }
|
|
278
|
|
279
|
58
|
280 ngx_int_t
|
324
|
281 ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
|
58
|
282 {
|
|
283 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
126
|
284
|
58
|
285 /* kqueue, epoll */
|
|
286
|
|
287 if (!rev->active && !rev->ready) {
|
|
288 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
|
|
289 == NGX_ERROR)
|
|
290 {
|
|
291 return NGX_ERROR;
|
|
292 }
|
|
293 }
|
126
|
294
|
58
|
295 return NGX_OK;
|
|
296
|
|
297 } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
|
298
|
|
299 /* select, poll, /dev/poll */
|
|
300
|
|
301 if (!rev->active && !rev->ready) {
|
|
302 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
|
|
303 == NGX_ERROR)
|
|
304 {
|
|
305 return NGX_ERROR;
|
|
306 }
|
|
307
|
|
308 return NGX_OK;
|
|
309 }
|
|
310
|
|
311 if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
|
|
312 if (ngx_del_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT | flags)
|
|
313 == NGX_ERROR)
|
|
314 {
|
|
315 return NGX_ERROR;
|
|
316 }
|
|
317
|
|
318 return NGX_OK;
|
|
319 }
|
|
320
|
236
|
321 } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
|
58
|
322
|
|
323 /* event ports */
|
|
324
|
236
|
325 if (!rev->active && !rev->ready) {
|
|
326 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
58
|
327 return NGX_ERROR;
|
|
328 }
|
236
|
329
|
|
330 return NGX_OK;
|
58
|
331 }
|
126
|
332
|
236
|
333 if (rev->oneshot && !rev->ready) {
|
|
334 if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
|
335 return NGX_ERROR;
|
|
336 }
|
|
337
|
|
338 return NGX_OK;
|
|
339 }
|
58
|
340 }
|
|
341
|
|
342 /* aio, iocp, rtsig */
|
|
343
|
|
344 return NGX_OK;
|
|
345 }
|
|
346
|
|
347
|
|
348 ngx_int_t
|
|
349 ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
|
|
350 {
|
|
351 ngx_connection_t *c;
|
|
352
|
|
353 if (lowat) {
|
236
|
354 c = wev->data;
|
58
|
355
|
|
356 if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
|
|
357 return NGX_ERROR;
|
|
358 }
|
|
359 }
|
|
360
|
|
361 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
|
362
|
|
363 /* kqueue, epoll */
|
|
364
|
|
365 if (!wev->active && !wev->ready) {
|
|
366 if (ngx_add_event(wev, NGX_WRITE_EVENT,
|
|
367 NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
|
|
368 == NGX_ERROR)
|
|
369 {
|
|
370 return NGX_ERROR;
|
|
371 }
|
|
372 }
|
|
373
|
|
374 return NGX_OK;
|
|
375
|
|
376 } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
|
377
|
|
378 /* select, poll, /dev/poll */
|
|
379
|
|
380 if (!wev->active && !wev->ready) {
|
|
381 if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
|
|
382 == NGX_ERROR)
|
|
383 {
|
|
384 return NGX_ERROR;
|
|
385 }
|
|
386
|
|
387 return NGX_OK;
|
|
388 }
|
|
389
|
|
390 if (wev->active && wev->ready) {
|
|
391 if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
|
|
392 == NGX_ERROR)
|
|
393 {
|
|
394 return NGX_ERROR;
|
|
395 }
|
|
396
|
|
397 return NGX_OK;
|
|
398 }
|
|
399
|
236
|
400 } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
|
58
|
401
|
|
402 /* event ports */
|
|
403
|
236
|
404 if (!wev->active && !wev->ready) {
|
|
405 if (ngx_add_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
58
|
406 return NGX_ERROR;
|
|
407 }
|
236
|
408
|
|
409 return NGX_OK;
|
58
|
410 }
|
126
|
411
|
236
|
412 if (wev->oneshot && wev->ready) {
|
|
413 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
|
414 return NGX_ERROR;
|
|
415 }
|
|
416
|
|
417 return NGX_OK;
|
|
418 }
|
58
|
419 }
|
|
420
|
|
421 /* aio, iocp, rtsig */
|
|
422
|
|
423 return NGX_OK;
|
|
424 }
|
|
425
|
|
426
|
672
|
427 static char *
|
|
428 ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
|
429 {
|
|
430 if (ngx_get_conf(cycle->conf_ctx, ngx_events_module) == NULL) {
|
|
431 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
|
|
432 "no \"events\" section in configuration");
|
|
433 return NGX_CONF_ERROR;
|
|
434 }
|
|
435
|
|
436 return NGX_CONF_OK;
|
|
437 }
|
|
438
|
|
439
|
58
|
440 static ngx_int_t
|
|
441 ngx_event_module_init(ngx_cycle_t *cycle)
|
0
|
442 {
|
92
|
443 void ***cf;
|
154
|
444 u_char *shared;
|
160
|
445 size_t size, cl;
|
356
|
446 ngx_shm_t shm;
|
516
|
447 ngx_time_t *tp;
|
112
|
448 ngx_core_conf_t *ccf;
|
356
|
449 ngx_event_conf_t *ecf;
|
22
|
450
|
|
451 cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
|
|
452 ecf = (*cf)[ngx_event_core_module.ctx_index];
|
|
453
|
480
|
454 if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) {
|
190
|
455 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
|
|
456 "using the \"%s\" event method", ecf->name);
|
|
457 }
|
22
|
458
|
112
|
459 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
0
|
460
|
112
|
461 ngx_timer_resolution = ccf->timer_resolution;
|
|
462
|
|
463 #if !(NGX_WIN32)
|
356
|
464 {
|
|
465 ngx_int_t limit;
|
|
466 struct rlimit rlmt;
|
0
|
467
|
92
|
468 if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
|
|
469 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
|
470 "getrlimit(RLIMIT_NOFILE) failed, ignored");
|
|
471
|
|
472 } else {
|
|
473 if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur
|
|
474 && (ccf->rlimit_nofile == NGX_CONF_UNSET
|
|
475 || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile))
|
|
476 {
|
|
477 limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ?
|
|
478 (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile;
|
|
479
|
|
480 ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
|
672
|
481 "%ui worker_connections exceed "
|
92
|
482 "open file resource limit: %i",
|
|
483 ecf->connections, limit);
|
|
484 }
|
|
485 }
|
356
|
486 }
|
154
|
487 #endif /* !(NGX_WIN32) */
|
|
488
|
92
|
489
|
160
|
490 if (ccf->master == 0) {
|
0
|
491 return NGX_OK;
|
|
492 }
|
|
493
|
160
|
494 if (ngx_accept_mutex_ptr) {
|
|
495 return NGX_OK;
|
|
496 }
|
|
497
|
|
498
|
672
|
499 /* cl should be equal to or greater than cache line size */
|
160
|
500
|
|
501 cl = 128;
|
|
502
|
|
503 size = cl /* ngx_accept_mutex */
|
516
|
504 + cl /* ngx_connection_counter */
|
|
505 + cl; /* ngx_temp_number */
|
0
|
506
|
|
507 #if (NGX_STAT_STUB)
|
|
508
|
160
|
509 size += cl /* ngx_stat_accepted */
|
|
510 + cl /* ngx_stat_handled */
|
|
511 + cl /* ngx_stat_requests */
|
|
512 + cl /* ngx_stat_active */
|
|
513 + cl /* ngx_stat_reading */
|
|
514 + cl; /* ngx_stat_writing */
|
0
|
515
|
|
516 #endif
|
|
517
|
154
|
518 shm.size = size;
|
480
|
519 shm.name.len = sizeof("nginx_shared_zone");
|
|
520 shm.name.data = (u_char *) "nginx_shared_zone";
|
154
|
521 shm.log = cycle->log;
|
|
522
|
|
523 if (ngx_shm_alloc(&shm) != NGX_OK) {
|
0
|
524 return NGX_ERROR;
|
|
525 }
|
|
526
|
154
|
527 shared = shm.addr;
|
|
528
|
0
|
529 ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
|
624
|
530 ngx_accept_mutex.spin = (ngx_uint_t) -1;
|
160
|
531
|
650
|
532 if (ngx_shmtx_create(&ngx_accept_mutex, (ngx_shmtx_sh_t *) shared,
|
|
533 cycle->lock_file.data)
|
160
|
534 != NGX_OK)
|
|
535 {
|
|
536 return NGX_ERROR;
|
|
537 }
|
|
538
|
|
539 ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
|
0
|
540
|
480
|
541 (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
|
112
|
542
|
0
|
543 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
10
|
544 "counter: %p, %d",
|
0
|
545 ngx_connection_counter, *ngx_connection_counter);
|
|
546
|
516
|
547 ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);
|
|
548
|
|
549 tp = ngx_timeofday();
|
|
550
|
|
551 ngx_random_number = (tp->msec << 16) + ngx_pid;
|
|
552
|
|
553 #if (NGX_STAT_STUB)
|
|
554
|
|
555 ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
|
|
556 ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
|
|
557 ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
|
|
558 ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
|
|
559 ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
|
|
560 ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
|
|
561
|
|
562 #endif
|
|
563
|
0
|
564 return NGX_OK;
|
|
565 }
|
|
566
|
|
567
|
112
|
568 #if !(NGX_WIN32)
|
|
569
|
682
|
570 static void
|
112
|
571 ngx_timer_signal_handler(int signo)
|
|
572 {
|
|
573 ngx_event_timer_alarm = 1;
|
|
574
|
|
575 #if 1
|
|
576 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
|
|
577 #endif
|
|
578 }
|
|
579
|
|
580 #endif
|
|
581
|
|
582
|
58
|
583 static ngx_int_t
|
|
584 ngx_event_process_init(ngx_cycle_t *cycle)
|
0
|
585 {
|
|
586 ngx_uint_t m, i;
|
|
587 ngx_event_t *rev, *wev;
|
92
|
588 ngx_listening_t *ls;
|
|
589 ngx_connection_t *c, *next, *old;
|
0
|
590 ngx_core_conf_t *ccf;
|
|
591 ngx_event_conf_t *ecf;
|
|
592 ngx_event_module_t *module;
|
|
593
|
|
594 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
|
595 ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
|
|
596
|
258
|
597 if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
|
160
|
598 ngx_use_accept_mutex = 1;
|
0
|
599 ngx_accept_mutex_held = 0;
|
|
600 ngx_accept_mutex_delay = ecf->accept_mutex_delay;
|
160
|
601
|
|
602 } else {
|
|
603 ngx_use_accept_mutex = 0;
|
0
|
604 }
|
|
605
|
|
606 #if (NGX_THREADS)
|
50
|
607 ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);
|
|
608 if (ngx_posted_events_mutex == NULL) {
|
0
|
609 return NGX_ERROR;
|
|
610 }
|
|
611 #endif
|
|
612
|
|
613 if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
|
|
614 return NGX_ERROR;
|
|
615 }
|
|
616
|
|
617 for (m = 0; ngx_modules[m]; m++) {
|
|
618 if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
|
|
619 continue;
|
|
620 }
|
|
621
|
384
|
622 if (ngx_modules[m]->ctx_index != ecf->use) {
|
|
623 continue;
|
0
|
624 }
|
384
|
625
|
|
626 module = ngx_modules[m]->ctx;
|
|
627
|
|
628 if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
|
|
629 /* fatal */
|
|
630 exit(2);
|
|
631 }
|
|
632
|
|
633 break;
|
0
|
634 }
|
|
635
|
92
|
636 #if !(NGX_WIN32)
|
|
637
|
112
|
638 if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
|
356
|
639 struct sigaction sa;
|
|
640 struct itimerval itv;
|
112
|
641
|
|
642 ngx_memzero(&sa, sizeof(struct sigaction));
|
|
643 sa.sa_handler = ngx_timer_signal_handler;
|
|
644 sigemptyset(&sa.sa_mask);
|
|
645
|
|
646 if (sigaction(SIGALRM, &sa, NULL) == -1) {
|
|
647 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
|
648 "sigaction(SIGALRM) failed");
|
|
649 return NGX_ERROR;
|
|
650 }
|
|
651
|
|
652 itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
|
|
653 itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
|
|
654 itv.it_value.tv_sec = ngx_timer_resolution / 1000;
|
|
655 itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;
|
|
656
|
|
657 if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
|
|
658 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
|
659 "setitimer() failed");
|
126
|
660 }
|
112
|
661 }
|
|
662
|
92
|
663 if (ngx_event_flags & NGX_USE_FD_EVENT) {
|
356
|
664 struct rlimit rlmt;
|
92
|
665
|
|
666 if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
|
|
667 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
|
668 "getrlimit(RLIMIT_NOFILE) failed");
|
|
669 return NGX_ERROR;
|
|
670 }
|
|
671
|
|
672 cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;
|
|
673
|
|
674 cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
|
|
675 cycle->log);
|
|
676 if (cycle->files == NULL) {
|
|
677 return NGX_ERROR;
|
|
678 }
|
|
679 }
|
|
680
|
|
681 #endif
|
|
682
|
384
|
683 cycle->connections =
|
|
684 ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
|
110
|
685 if (cycle->connections == NULL) {
|
0
|
686 return NGX_ERROR;
|
|
687 }
|
|
688
|
110
|
689 c = cycle->connections;
|
0
|
690
|
384
|
691 cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
|
0
|
692 cycle->log);
|
110
|
693 if (cycle->read_events == NULL) {
|
0
|
694 return NGX_ERROR;
|
|
695 }
|
|
696
|
110
|
697 rev = cycle->read_events;
|
0
|
698 for (i = 0; i < cycle->connection_n; i++) {
|
|
699 rev[i].closed = 1;
|
30
|
700 rev[i].instance = 1;
|
0
|
701 #if (NGX_THREADS)
|
|
702 rev[i].lock = &c[i].lock;
|
|
703 rev[i].own_lock = &c[i].lock;
|
|
704 #endif
|
|
705 }
|
|
706
|
384
|
707 cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
|
30
|
708 cycle->log);
|
110
|
709 if (cycle->write_events == NULL) {
|
0
|
710 return NGX_ERROR;
|
|
711 }
|
|
712
|
110
|
713 wev = cycle->write_events;
|
0
|
714 for (i = 0; i < cycle->connection_n; i++) {
|
|
715 wev[i].closed = 1;
|
|
716 #if (NGX_THREADS)
|
|
717 wev[i].lock = &c[i].lock;
|
|
718 wev[i].own_lock = &c[i].lock;
|
|
719 #endif
|
|
720 }
|
|
721
|
92
|
722 i = cycle->connection_n;
|
|
723 next = NULL;
|
|
724
|
|
725 do {
|
|
726 i--;
|
|
727
|
|
728 c[i].data = next;
|
110
|
729 c[i].read = &cycle->read_events[i];
|
|
730 c[i].write = &cycle->write_events[i];
|
92
|
731 c[i].fd = (ngx_socket_t) -1;
|
|
732
|
|
733 next = &c[i];
|
|
734
|
|
735 #if (NGX_THREADS)
|
|
736 c[i].lock = 0;
|
|
737 #endif
|
|
738 } while (i);
|
|
739
|
|
740 cycle->free_connections = next;
|
384
|
741 cycle->free_connection_n = cycle->connection_n;
|
92
|
742
|
0
|
743 /* for each listening socket */
|
|
744
|
92
|
745 ls = cycle->listening.elts;
|
0
|
746 for (i = 0; i < cycle->listening.nelts; i++) {
|
|
747
|
92
|
748 c = ngx_get_connection(ls[i].fd, cycle->log);
|
0
|
749
|
92
|
750 if (c == NULL) {
|
|
751 return NGX_ERROR;
|
|
752 }
|
0
|
753
|
92
|
754 c->log = &ls[i].log;
|
|
755
|
|
756 c->listening = &ls[i];
|
|
757 ls[i].connection = c;
|
|
758
|
110
|
759 rev = c->read;
|
0
|
760
|
|
761 rev->log = c->log;
|
|
762 rev->accept = 1;
|
|
763
|
18
|
764 #if (NGX_HAVE_DEFERRED_ACCEPT)
|
92
|
765 rev->deferred_accept = ls[i].deferred_accept;
|
0
|
766 #endif
|
|
767
|
|
768 if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
|
92
|
769 if (ls[i].previous) {
|
0
|
770
|
|
771 /*
|
|
772 * delete the old accept events that were bound to
|
|
773 * the old cycle read events array
|
|
774 */
|
|
775
|
92
|
776 old = ls[i].previous->connection;
|
|
777
|
|
778 if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
|
|
779 == NGX_ERROR)
|
0
|
780 {
|
|
781 return NGX_ERROR;
|
|
782 }
|
|
783
|
92
|
784 old->fd = (ngx_socket_t) -1;
|
0
|
785 }
|
|
786 }
|
|
787
|
10
|
788 #if (NGX_WIN32)
|
0
|
789
|
|
790 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
|
356
|
791 ngx_iocp_conf_t *iocpcf;
|
|
792
|
58
|
793 rev->handler = ngx_event_acceptex;
|
0
|
794
|
484
|
795 if (ngx_use_accept_mutex) {
|
|
796 continue;
|
|
797 }
|
|
798
|
0
|
799 if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
|
|
800 return NGX_ERROR;
|
|
801 }
|
|
802
|
92
|
803 ls[i].log.handler = ngx_acceptex_log_error;
|
|
804
|
0
|
805 iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
|
92
|
806 if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)
|
|
807 == NGX_ERROR)
|
0
|
808 {
|
|
809 return NGX_ERROR;
|
|
810 }
|
|
811
|
|
812 } else {
|
58
|
813 rev->handler = ngx_event_accept;
|
10
|
814
|
484
|
815 if (ngx_use_accept_mutex) {
|
|
816 continue;
|
|
817 }
|
|
818
|
0
|
819 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
|
820 return NGX_ERROR;
|
|
821 }
|
|
822 }
|
|
823
|
|
824 #else
|
|
825
|
58
|
826 rev->handler = ngx_event_accept;
|
0
|
827
|
160
|
828 if (ngx_use_accept_mutex) {
|
0
|
829 continue;
|
|
830 }
|
|
831
|
|
832 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
|
|
833 if (ngx_add_conn(c) == NGX_ERROR) {
|
|
834 return NGX_ERROR;
|
|
835 }
|
|
836
|
|
837 } else {
|
|
838 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
|
839 return NGX_ERROR;
|
|
840 }
|
|
841 }
|
|
842
|
|
843 #endif
|
92
|
844
|
0
|
845 }
|
|
846
|
|
847 return NGX_OK;
|
|
848 }
|
|
849
|
|
850
|
58
|
851 ngx_int_t
|
|
852 ngx_send_lowat(ngx_connection_t *c, size_t lowat)
|
2
|
853 {
|
|
854 int sndlowat;
|
|
855
|
4
|
856 #if (NGX_HAVE_LOWAT_EVENT)
|
2
|
857
|
4
|
858 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
|
2
|
859 c->write->available = lowat;
|
|
860 return NGX_OK;
|
|
861 }
|
|
862
|
|
863 #endif
|
126
|
864
|
2
|
865 if (lowat == 0 || c->sndlowat) {
|
|
866 return NGX_OK;
|
|
867 }
|
|
868
|
|
869 sndlowat = (int) lowat;
|
|
870
|
|
871 if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,
|
282
|
872 (const void *) &sndlowat, sizeof(int))
|
|
873 == -1)
|
2
|
874 {
|
|
875 ngx_connection_error(c, ngx_socket_errno,
|
|
876 "setsockopt(SO_SNDLOWAT) failed");
|
|
877 return NGX_ERROR;
|
|
878 }
|
|
879
|
|
880 c->sndlowat = 1;
|
|
881
|
|
882 return NGX_OK;
|
|
883 }
|
|
884
|
|
885
|
58
|
886 static char *
|
|
887 ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
0
|
888 {
|
50
|
889 char *rv;
|
0
|
890 void ***ctx;
|
50
|
891 ngx_uint_t i;
|
0
|
892 ngx_conf_t pcf;
|
50
|
893 ngx_event_module_t *m;
|
0
|
894
|
|
895 /* count the number of the event modules and set up their indices */
|
|
896
|
|
897 ngx_event_max_module = 0;
|
50
|
898 for (i = 0; ngx_modules[i]; i++) {
|
|
899 if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
|
0
|
900 continue;
|
|
901 }
|
|
902
|
50
|
903 ngx_modules[i]->ctx_index = ngx_event_max_module++;
|
0
|
904 }
|
|
905
|
50
|
906 ctx = ngx_pcalloc(cf->pool, sizeof(void *));
|
|
907 if (ctx == NULL) {
|
|
908 return NGX_CONF_ERROR;
|
|
909 }
|
0
|
910
|
50
|
911 *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
|
|
912 if (*ctx == NULL) {
|
|
913 return NGX_CONF_ERROR;
|
|
914 }
|
0
|
915
|
|
916 *(void **) conf = ctx;
|
|
917
|
50
|
918 for (i = 0; ngx_modules[i]; i++) {
|
|
919 if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
|
0
|
920 continue;
|
|
921 }
|
|
922
|
50
|
923 m = ngx_modules[i]->ctx;
|
0
|
924
|
50
|
925 if (m->create_conf) {
|
|
926 (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
|
|
927 if ((*ctx)[ngx_modules[i]->ctx_index] == NULL) {
|
|
928 return NGX_CONF_ERROR;
|
|
929 }
|
0
|
930 }
|
|
931 }
|
|
932
|
|
933 pcf = *cf;
|
|
934 cf->ctx = ctx;
|
|
935 cf->module_type = NGX_EVENT_MODULE;
|
|
936 cf->cmd_type = NGX_EVENT_CONF;
|
50
|
937
|
0
|
938 rv = ngx_conf_parse(cf, NULL);
|
50
|
939
|
0
|
940 *cf = pcf;
|
|
941
|
|
942 if (rv != NGX_CONF_OK)
|
|
943 return rv;
|
|
944
|
50
|
945 for (i = 0; ngx_modules[i]; i++) {
|
|
946 if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
|
0
|
947 continue;
|
|
948 }
|
|
949
|
50
|
950 m = ngx_modules[i]->ctx;
|
0
|
951
|
50
|
952 if (m->init_conf) {
|
|
953 rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]);
|
0
|
954 if (rv != NGX_CONF_OK) {
|
|
955 return rv;
|
|
956 }
|
|
957 }
|
|
958 }
|
|
959
|
|
960 return NGX_CONF_OK;
|
|
961 }
|
|
962
|
|
963
|
58
|
964 static char *
|
|
965 ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
0
|
966 {
|
|
967 ngx_event_conf_t *ecf = conf;
|
|
968
|
|
969 ngx_str_t *value;
|
|
970
|
|
971 if (ecf->connections != NGX_CONF_UNSET_UINT) {
|
378
|
972 return "is duplicate";
|
0
|
973 }
|
|
974
|
130
|
975 if (ngx_strcmp(cmd->name.data, "connections") == 0) {
|
|
976 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
|
977 "the \"connections\" directive is deprecated, "
|
|
978 "use the \"worker_connections\" directive instead");
|
|
979 }
|
|
980
|
0
|
981 value = cf->args->elts;
|
|
982 ecf->connections = ngx_atoi(value[1].data, value[1].len);
|
|
983 if (ecf->connections == (ngx_uint_t) NGX_ERROR) {
|
|
984 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
10
|
985 "invalid number \"%V\"", &value[1]);
|
0
|
986
|
|
987 return NGX_CONF_ERROR;
|
|
988 }
|
|
989
|
|
990 cf->cycle->connection_n = ecf->connections;
|
|
991
|
|
992 return NGX_CONF_OK;
|
|
993 }
|
|
994
|
|
995
|
58
|
996 static char *
|
|
997 ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
0
|
998 {
|
|
999 ngx_event_conf_t *ecf = conf;
|
|
1000
|
|
1001 ngx_int_t m;
|
|
1002 ngx_str_t *value;
|
|
1003 ngx_event_conf_t *old_ecf;
|
|
1004 ngx_event_module_t *module;
|
|
1005
|
|
1006 if (ecf->use != NGX_CONF_UNSET_UINT) {
|
378
|
1007 return "is duplicate";
|
0
|
1008 }
|
|
1009
|
|
1010 value = cf->args->elts;
|
|
1011
|
|
1012 if (cf->cycle->old_cycle->conf_ctx) {
|
|
1013 old_ecf = ngx_event_get_conf(cf->cycle->old_cycle->conf_ctx,
|
|
1014 ngx_event_core_module);
|
|
1015 } else {
|
|
1016 old_ecf = NULL;
|
|
1017 }
|
|
1018
|
|
1019
|
|
1020 for (m = 0; ngx_modules[m]; m++) {
|
|
1021 if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
|
|
1022 continue;
|
|
1023 }
|
|
1024
|
|
1025 module = ngx_modules[m]->ctx;
|
|
1026 if (module->name->len == value[1].len) {
|
|
1027 if (ngx_strcmp(module->name->data, value[1].data) == 0) {
|
|
1028 ecf->use = ngx_modules[m]->ctx_index;
|
|
1029 ecf->name = module->name->data;
|
|
1030
|
|
1031 if (ngx_process == NGX_PROCESS_SINGLE
|
|
1032 && old_ecf
|
|
1033 && old_ecf->use != ecf->use)
|
|
1034 {
|
|
1035 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
16
|
1036 "when the server runs without a master process "
|
|
1037 "the \"%V\" event type must be the same as "
|
|
1038 "in previous configuration - \"%s\" "
|
640
|
1039 "and it cannot be changed on the fly, "
|
16
|
1040 "to change it you need to stop server "
|
|
1041 "and start it again",
|
|
1042 &value[1], old_ecf->name);
|
0
|
1043
|
|
1044 return NGX_CONF_ERROR;
|
|
1045 }
|
|
1046
|
|
1047 return NGX_CONF_OK;
|
|
1048 }
|
|
1049 }
|
|
1050 }
|
|
1051
|
|
1052 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
10
|
1053 "invalid event type \"%V\"", &value[1]);
|
0
|
1054
|
|
1055 return NGX_CONF_ERROR;
|
|
1056 }
|
|
1057
|
|
1058
|
58
|
1059 static char *
|
|
1060 ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
0
|
1061 {
|
|
1062 #if (NGX_DEBUG)
|
|
1063 ngx_event_conf_t *ecf = conf;
|
|
1064
|
682
|
1065 ngx_int_t rc;
|
|
1066 ngx_str_t *value;
|
|
1067 ngx_url_t u;
|
|
1068 ngx_cidr_t c, *cidr;
|
|
1069 ngx_uint_t i;
|
|
1070 struct sockaddr_in *sin;
|
|
1071 #if (NGX_HAVE_INET6)
|
|
1072 struct sockaddr_in6 *sin6;
|
|
1073 #endif
|
0
|
1074
|
|
1075 value = cf->args->elts;
|
|
1076
|
674
|
1077 #if (NGX_HAVE_UNIX_DOMAIN)
|
|
1078
|
|
1079 if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
682
|
1080 cidr = ngx_array_push(&ecf->debug_connection);
|
|
1081 if (cidr == NULL) {
|
|
1082 return NGX_CONF_ERROR;
|
|
1083 }
|
|
1084
|
|
1085 cidr->family = AF_UNIX;
|
|
1086 return NGX_CONF_OK;
|
674
|
1087 }
|
|
1088
|
|
1089 #endif
|
|
1090
|
682
|
1091 rc = ngx_ptocidr(&value[1], &c);
|
326
|
1092
|
682
|
1093 if (rc != NGX_ERROR) {
|
|
1094 if (rc == NGX_DONE) {
|
|
1095 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
|
1096 "low address bits of %V are meaningless",
|
|
1097 &value[1]);
|
|
1098 }
|
326
|
1099
|
682
|
1100 cidr = ngx_array_push(&ecf->debug_connection);
|
|
1101 if (cidr == NULL) {
|
|
1102 return NGX_CONF_ERROR;
|
|
1103 }
|
|
1104
|
|
1105 *cidr = c;
|
|
1106
|
326
|
1107 return NGX_CONF_OK;
|
0
|
1108 }
|
|
1109
|
682
|
1110 ngx_memzero(&u, sizeof(ngx_url_t));
|
|
1111 u.host = value[1];
|
0
|
1112
|
682
|
1113 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
|
|
1114 if (u.err) {
|
|
1115 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
|
1116 "%s in debug_connection \"%V\"",
|
|
1117 u.err, &u.host);
|
|
1118 }
|
|
1119
|
|
1120 return NGX_CONF_ERROR;
|
|
1121 }
|
|
1122
|
|
1123 cidr = ngx_array_push_n(&ecf->debug_connection, u.naddrs);
|
|
1124 if (cidr == NULL) {
|
0
|
1125 return NGX_CONF_ERROR;
|
|
1126 }
|
|
1127
|
682
|
1128 ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
|
|
1129
|
|
1130 for (i = 0; i < u.naddrs; i++) {
|
|
1131 cidr[i].family = u.addrs[i].sockaddr->sa_family;
|
|
1132
|
|
1133 switch (cidr[i].family) {
|
|
1134
|
|
1135 #if (NGX_HAVE_INET6)
|
|
1136 case AF_INET6:
|
|
1137 sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
|
|
1138 cidr[i].u.in6.addr = sin6->sin6_addr;
|
|
1139 ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
|
|
1140 break;
|
|
1141 #endif
|
|
1142
|
|
1143 default: /* AF_INET */
|
|
1144 sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
|
|
1145 cidr[i].u.in.addr = sin->sin_addr.s_addr;
|
|
1146 cidr[i].u.in.mask = 0xffffffff;
|
|
1147 break;
|
|
1148 }
|
|
1149 }
|
0
|
1150
|
|
1151 #else
|
|
1152
|
|
1153 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
|
1154 "\"debug_connection\" is ignored, you need to rebuild "
|
|
1155 "nginx using --with-debug option to enable it");
|
|
1156
|
|
1157 #endif
|
|
1158
|
326
|
1159 return NGX_CONF_OK;
|
0
|
1160 }
|
|
1161
|
|
1162
|
58
|
1163 static void *
|
672
|
1164 ngx_event_core_create_conf(ngx_cycle_t *cycle)
|
0
|
1165 {
|
|
1166 ngx_event_conf_t *ecf;
|
|
1167
|
50
|
1168 ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));
|
|
1169 if (ecf == NULL) {
|
496
|
1170 return NULL;
|
50
|
1171 }
|
0
|
1172
|
|
1173 ecf->connections = NGX_CONF_UNSET_UINT;
|
|
1174 ecf->use = NGX_CONF_UNSET_UINT;
|
|
1175 ecf->multi_accept = NGX_CONF_UNSET;
|
|
1176 ecf->accept_mutex = NGX_CONF_UNSET;
|
|
1177 ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;
|
|
1178 ecf->name = (void *) NGX_CONF_UNSET;
|
|
1179
|
|
1180 #if (NGX_DEBUG)
|
50
|
1181
|
|
1182 if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
|
674
|
1183 sizeof(ngx_cidr_t)) == NGX_ERROR)
|
50
|
1184 {
|
496
|
1185 return NULL;
|
50
|
1186 }
|
|
1187
|
0
|
1188 #endif
|
|
1189
|
|
1190 return ecf;
|
|
1191 }
|
|
1192
|
|
1193
|
58
|
1194 static char *
|
672
|
1195 ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
|
0
|
1196 {
|
|
1197 ngx_event_conf_t *ecf = conf;
|
16
|
1198
|
50
|
1199 #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
|
|
1200 int fd;
|
|
1201 #endif
|
|
1202 #if (NGX_HAVE_RTSIG)
|
|
1203 ngx_uint_t rtsig;
|
122
|
1204 ngx_core_conf_t *ccf;
|
50
|
1205 #endif
|
384
|
1206 ngx_int_t i;
|
16
|
1207 ngx_module_t *module;
|
|
1208 ngx_event_module_t *event_module;
|
|
1209
|
|
1210 module = NULL;
|
|
1211
|
18
|
1212 #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
|
16
|
1213
|
|
1214 fd = epoll_create(100);
|
|
1215
|
|
1216 if (fd != -1) {
|
684
|
1217 (void) close(fd);
|
16
|
1218 module = &ngx_epoll_module;
|
|
1219
|
|
1220 } else if (ngx_errno != NGX_ENOSYS) {
|
|
1221 module = &ngx_epoll_module;
|
|
1222 }
|
|
1223
|
|
1224 #endif
|
|
1225
|
18
|
1226 #if (NGX_HAVE_RTSIG)
|
16
|
1227
|
|
1228 if (module == NULL) {
|
|
1229 module = &ngx_rtsig_module;
|
|
1230 rtsig = 1;
|
50
|
1231
|
|
1232 } else {
|
|
1233 rtsig = 0;
|
16
|
1234 }
|
|
1235
|
|
1236 #endif
|
|
1237
|
18
|
1238 #if (NGX_HAVE_DEVPOLL)
|
16
|
1239
|
|
1240 module = &ngx_devpoll_module;
|
|
1241
|
0
|
1242 #endif
|
|
1243
|
18
|
1244 #if (NGX_HAVE_KQUEUE)
|
0
|
1245
|
16
|
1246 module = &ngx_kqueue_module;
|
0
|
1247
|
16
|
1248 #endif
|
0
|
1249
|
18
|
1250 #if (NGX_HAVE_SELECT)
|
0
|
1251
|
16
|
1252 if (module == NULL) {
|
|
1253 module = &ngx_select_module;
|
|
1254 }
|
|
1255
|
0
|
1256 #endif
|
|
1257
|
16
|
1258 if (module == NULL) {
|
|
1259 for (i = 0; ngx_modules[i]; i++) {
|
384
|
1260
|
|
1261 if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
|
|
1262 continue;
|
|
1263 }
|
|
1264
|
|
1265 event_module = ngx_modules[i]->ctx;
|
0
|
1266
|
384
|
1267 if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0)
|
|
1268 {
|
|
1269 continue;
|
|
1270 }
|
0
|
1271
|
384
|
1272 module = ngx_modules[i];
|
|
1273 break;
|
0
|
1274 }
|
|
1275 }
|
|
1276
|
16
|
1277 if (module == NULL) {
|
0
|
1278 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
|
|
1279 return NGX_CONF_ERROR;
|
|
1280 }
|
|
1281
|
384
|
1282 ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);
|
16
|
1283 cycle->connection_n = ecf->connections;
|
0
|
1284
|
212
|
1285 ngx_conf_init_uint_value(ecf->use, module->ctx_index);
|
0
|
1286
|
16
|
1287 event_module = module->ctx;
|
|
1288 ngx_conf_init_ptr_value(ecf->name, event_module->name->data);
|
0
|
1289
|
|
1290 ngx_conf_init_value(ecf->multi_accept, 0);
|
|
1291 ngx_conf_init_value(ecf->accept_mutex, 1);
|
|
1292 ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
|
|
1293
|
16
|
1294
|
50
|
1295 #if (NGX_HAVE_RTSIG)
|
|
1296
|
|
1297 if (!rtsig) {
|
|
1298 return NGX_CONF_OK;
|
|
1299 }
|
|
1300
|
|
1301 if (ecf->accept_mutex) {
|
16
|
1302 return NGX_CONF_OK;
|
0
|
1303 }
|
16
|
1304
|
|
1305 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
0
|
1306
|
16
|
1307 if (ccf->worker_processes == 0) {
|
|
1308 return NGX_CONF_OK;
|
|
1309 }
|
|
1310
|
|
1311 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
|
|
1312 "the \"rtsig\" method requires \"accept_mutex\" to be on");
|
|
1313
|
|
1314 return NGX_CONF_ERROR;
|
122
|
1315
|
|
1316 #else
|
|
1317
|
|
1318 return NGX_CONF_OK;
|
|
1319
|
|
1320 #endif
|
0
|
1321 }
|