Klaus Demo nginx / 33b8e5b
Removed the obsolete rtsig module. Ruslan Ermilov 7 years ago
14 changed file(s) with 29 addition(s) and 916 deletion(s). Raw diff Collapse all Expand all
4646 have=NGX_TEST_BUILD_EPOLL . auto/have
4747 EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
4848 CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
49 fi
50
51 if [ $NGX_TEST_BUILD_RTSIG = YES ]; then
52 have=NGX_HAVE_RTSIG . auto/have
53 have=NGX_TEST_BUILD_RTSIG . auto/have
54 EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE"
55 CORE_SRCS="$CORE_SRCS $RTSIG_SRCS"
5649 fi
5750
5851 if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
2929 NGX_TEST_BUILD_DEVPOLL=NO
3030 NGX_TEST_BUILD_EVENTPORT=NO
3131 NGX_TEST_BUILD_EPOLL=NO
32 NGX_TEST_BUILD_RTSIG=NO
3332 NGX_TEST_BUILD_SOLARIS_SENDFILEV=NO
3433
3534 NGX_PLATFORM=
3736
3837 EVENT_FOUND=NO
3938
40 EVENT_RTSIG=NO
4139 EVENT_SELECT=NO
4240 EVENT_POLL=NO
4341
188186 --build=*) NGX_BUILD="$value" ;;
189187 --builddir=*) NGX_OBJS="$value" ;;
190188
191 --with-rtsig_module) EVENT_RTSIG=YES ;;
192189 --with-select_module) EVENT_SELECT=YES ;;
193190 --without-select_module) EVENT_SELECT=NONE ;;
194191 --with-poll_module) EVENT_POLL=YES ;;
326323 --test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;;
327324 --test-build-eventport) NGX_TEST_BUILD_EVENTPORT=YES ;;
328325 --test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;;
329 --test-build-rtsig) NGX_TEST_BUILD_RTSIG=YES ;;
330326 --test-build-solaris-sendfilev) NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;;
331327
332328 *)
361357 --build=NAME set build name
362358 --builddir=DIR set build directory
363359
364 --with-rtsig_module enable rtsig module
365360 --with-select_module enable select module
366361 --without-select_module disable select module
367362 --with-poll_module enable poll module
2323 -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1*256*256+\2*256/p'`))
2424
2525 version=${version:-0}
26
27
28 # enable the rt signals on Linux between 2.2.19 and 2.6.17
29
30 if [ \( $version -ge 131603 -a $version -lt 132626 \) -o $EVENT_RTSIG = YES ]
31 then
32 echo " + rt signals found"
33 have=NGX_HAVE_RTSIG . auto/have
34 EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE"
35 CORE_SRCS="$CORE_SRCS $RTSIG_SRCS"
36 EVENT_FOUND=YES
37 fi
3826
3927
4028 # posix_fadvise64() had been implemented in 2.5.60
123123 EPOLL_MODULE=ngx_epoll_module
124124 EPOLL_SRCS=src/event/modules/ngx_epoll_module.c
125125
126 RTSIG_MODULE=ngx_rtsig_module
127 RTSIG_SRCS=src/event/modules/ngx_rtsig_module.c
128
129126 IOCP_MODULE=ngx_iocp_module
130127 IOCP_SRCS=src/event/modules/ngx_iocp_module.c
131128
763763
764764 if (c) {
765765 if (c->read->active) {
766 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
767 ngx_del_conn(c, NGX_CLOSE_EVENT);
768
769 } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
766 if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
770767
771768 /*
772769 * it seems that Linux-2.6.x OpenVZ sends events
31033103 /* UDP sockets are always ready to write */
31043104 wev->ready = 1;
31053105
3106 if (ngx_add_event) {
3107
3108 event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ?
3109 /* kqueue, epoll */ NGX_CLEAR_EVENT:
3110 /* select, poll, /dev/poll */ NGX_LEVEL_EVENT;
3111 /* eventport event type has no meaning: oneshot only */
3112
3113 if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
3114 goto failed;
3115 }
3116
3117 } else {
3118 /* rtsig */
3119
3120 if (ngx_add_conn(c) == NGX_ERROR) {
3121 goto failed;
3122 }
3106 event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ?
3107 /* kqueue, epoll */ NGX_CLEAR_EVENT:
3108 /* select, poll, /dev/poll */ NGX_LEVEL_EVENT;
3109 /* eventport event type has no meaning: oneshot only */
3110
3111 if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
3112 goto failed;
31233113 }
31243114
31253115 return NGX_OK;
+0
-735
src/event/modules/ngx_rtsig_module.c less more
0
1 /*
2 * Copyright (C) Igor Sysoev
3 * Copyright (C) Nginx, Inc.
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10
11
12 #if (NGX_TEST_BUILD_RTSIG)
13
14 #if (NGX_DARWIN)
15
16 #define SIGRTMIN 33
17 #define si_fd __pad[0]
18
19 #else
20
21 #ifdef SIGRTMIN
22 #define si_fd _reason.__spare__.__spare2__[0]
23 #else
24 #define SIGRTMIN 33
25 #define si_fd __spare__[0]
26 #endif
27
28 #endif
29
30 #define F_SETSIG 10
31 #define KERN_RTSIGNR 30
32 #define KERN_RTSIGMAX 31
33
34 int sigtimedwait(const sigset_t *set, siginfo_t *info,
35 const struct timespec *timeout);
36
37 int sigtimedwait(const sigset_t *set, siginfo_t *info,
38 const struct timespec *timeout)
39 {
40 return -1;
41 }
42
43 int ngx_linux_rtsig_max;
44
45 #endif
46
47
48 typedef struct {
49 ngx_uint_t signo;
50 ngx_uint_t overflow_events;
51 ngx_uint_t overflow_test;
52 ngx_uint_t overflow_threshold;
53 } ngx_rtsig_conf_t;
54
55
56 extern ngx_event_module_t ngx_poll_module_ctx;
57
58 static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer);
59 static void ngx_rtsig_done(ngx_cycle_t *cycle);
60 static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c);
61 static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c,
62 ngx_uint_t flags);
63 static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle,
64 ngx_msec_t timer, ngx_uint_t flags);
65 static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle,
66 ngx_msec_t timer, ngx_uint_t flags);
67
68 static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle);
69 static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf);
70 static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf,
71 void *post, void *data);
72
73
74 static sigset_t set;
75 static ngx_uint_t overflow, overflow_current;
76 static struct pollfd *overflow_list;
77
78
79 static ngx_str_t rtsig_name = ngx_string("rtsig");
80
81 static ngx_conf_num_bounds_t ngx_overflow_threshold_bounds = {
82 ngx_check_ngx_overflow_threshold_bounds, 2, 10
83 };
84
85
86 static ngx_command_t ngx_rtsig_commands[] = {
87
88 { ngx_string("rtsig_signo"),
89 NGX_EVENT_CONF|NGX_CONF_TAKE1,
90 ngx_conf_set_num_slot,
91 0,
92 offsetof(ngx_rtsig_conf_t, signo),
93 NULL },
94
95 { ngx_string("rtsig_overflow_events"),
96 NGX_EVENT_CONF|NGX_CONF_TAKE1,
97 ngx_conf_set_num_slot,
98 0,
99 offsetof(ngx_rtsig_conf_t, overflow_events),
100 NULL },
101
102 { ngx_string("rtsig_overflow_test"),
103 NGX_EVENT_CONF|NGX_CONF_TAKE1,
104 ngx_conf_set_num_slot,
105 0,
106 offsetof(ngx_rtsig_conf_t, overflow_test),
107 NULL },
108
109 { ngx_string("rtsig_overflow_threshold"),
110 NGX_EVENT_CONF|NGX_CONF_TAKE1,
111 ngx_conf_set_num_slot,
112 0,
113 offsetof(ngx_rtsig_conf_t, overflow_threshold),
114 &ngx_overflow_threshold_bounds },
115
116 ngx_null_command
117 };
118
119
120 ngx_event_module_t ngx_rtsig_module_ctx = {
121 &rtsig_name,
122 ngx_rtsig_create_conf, /* create configuration */
123 ngx_rtsig_init_conf, /* init configuration */
124
125 {
126 NULL, /* add an event */
127 NULL, /* delete an event */
128 NULL, /* enable an event */
129 NULL, /* disable an event */
130 ngx_rtsig_add_connection, /* add an connection */
131 ngx_rtsig_del_connection, /* delete an connection */
132 NULL, /* trigger a notify */
133 ngx_rtsig_process_events, /* process the events */
134 ngx_rtsig_init, /* init the events */
135 ngx_rtsig_done, /* done the events */
136 }
137
138 };
139
140 ngx_module_t ngx_rtsig_module = {
141 NGX_MODULE_V1,
142 &ngx_rtsig_module_ctx, /* module context */
143 ngx_rtsig_commands, /* module directives */
144 NGX_EVENT_MODULE, /* module type */
145 NULL, /* init master */
146 NULL, /* init module */
147 NULL, /* init process */
148 NULL, /* init thread */
149 NULL, /* exit thread */
150 NULL, /* exit process */
151 NULL, /* exit master */
152 NGX_MODULE_V1_PADDING
153 };
154
155
156 static ngx_int_t
157 ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer)
158 {
159 ngx_rtsig_conf_t *rtscf;
160
161 rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
162
163 sigemptyset(&set);
164 sigaddset(&set, (int) rtscf->signo);
165 sigaddset(&set, (int) rtscf->signo + 1);
166 sigaddset(&set, SIGIO);
167 sigaddset(&set, SIGALRM);
168
169 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
170 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
171 "sigprocmask() failed");
172 return NGX_ERROR;
173 }
174
175 if (overflow_list) {
176 ngx_free(overflow_list);
177 }
178
179 overflow_list = ngx_alloc(sizeof(struct pollfd) * rtscf->overflow_events,
180 cycle->log);
181 if (overflow_list == NULL) {
182 return NGX_ERROR;
183 }
184
185 ngx_io = ngx_os_io;
186
187 ngx_event_actions = ngx_rtsig_module_ctx.actions;
188
189 ngx_event_flags = NGX_USE_RTSIG_EVENT
190 |NGX_USE_GREEDY_EVENT
191 |NGX_USE_FD_EVENT;
192
193 return NGX_OK;
194 }
195
196
197 static void
198 ngx_rtsig_done(ngx_cycle_t *cycle)
199 {
200 ngx_free(overflow_list);
201
202 overflow_list = NULL;
203 }
204
205
206 static ngx_int_t
207 ngx_rtsig_add_connection(ngx_connection_t *c)
208 {
209 ngx_uint_t signo;
210 ngx_rtsig_conf_t *rtscf;
211
212 if (c->read->accept && c->read->disabled) {
213
214 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
215 "rtsig enable connection: fd:%d", c->fd);
216
217 if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
218 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
219 "fcntl(F_SETOWN) failed");
220 return NGX_ERROR;
221 }
222
223 c->read->active = 1;
224 c->read->disabled = 0;
225 }
226
227 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
228
229 signo = rtscf->signo + c->read->instance;
230
231 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
232 "rtsig add connection: fd:%d signo:%ui", c->fd, signo);
233
234 if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) {
235 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
236 "fcntl(O_RDWR|O_NONBLOCK|O_ASYNC) failed");
237 return NGX_ERROR;
238 }
239
240 if (fcntl(c->fd, F_SETSIG, (int) signo) == -1) {
241 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
242 "fcntl(F_SETSIG) failed");
243 return NGX_ERROR;
244 }
245
246 if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
247 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
248 "fcntl(F_SETOWN) failed");
249 return NGX_ERROR;
250 }
251
252 #if (NGX_HAVE_ONESIGFD)
253 if (fcntl(c->fd, F_SETAUXFL, O_ONESIGFD) == -1) {
254 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
255 "fcntl(F_SETAUXFL) failed");
256 return NGX_ERROR;
257 }
258 #endif
259
260 c->read->active = 1;
261 c->write->active = 1;
262
263 return NGX_OK;
264 }
265
266
267 static ngx_int_t
268 ngx_rtsig_del_connection(ngx_connection_t *c, ngx_uint_t flags)
269 {
270 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
271 "rtsig del connection: fd:%d", c->fd);
272
273 if ((flags & NGX_DISABLE_EVENT) && c->read->accept) {
274
275 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
276 "rtsig disable connection: fd:%d", c->fd);
277
278 c->read->active = 0;
279 c->read->disabled = 1;
280 return NGX_OK;
281 }
282
283 if (flags & NGX_CLOSE_EVENT) {
284 c->read->active = 0;
285 c->write->active = 0;
286 return NGX_OK;
287 }
288
289 if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK) == -1) {
290 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
291 "fcntl(O_RDWR|O_NONBLOCK) failed");
292 return NGX_ERROR;
293 }
294
295 c->read->active = 0;
296 c->write->active = 0;
297
298 return NGX_OK;
299 }
300
301
302 static ngx_int_t
303 ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
304 {
305 int signo;
306 ngx_int_t instance;
307 ngx_err_t err;
308 siginfo_t si;
309 ngx_event_t *rev, *wev;
310 ngx_queue_t *queue;
311 struct timespec ts, *tp;
312 struct sigaction sa;
313 ngx_connection_t *c;
314 ngx_rtsig_conf_t *rtscf;
315
316 if (timer == NGX_TIMER_INFINITE) {
317 tp = NULL;
318
319 } else {
320 ts.tv_sec = timer / 1000;
321 ts.tv_nsec = (timer % 1000) * 1000000;
322 tp = &ts;
323 }
324
325 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
326 "rtsig timer: %M", timer);
327
328 /* Linux's sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */
329
330 signo = sigtimedwait(&set, &si, tp);
331
332 if (signo == -1) {
333 err = ngx_errno;
334
335 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
336 "rtsig signo:%d", signo);
337
338 if (flags & NGX_UPDATE_TIME) {
339 ngx_time_update();
340 }
341
342 if (err == NGX_EAGAIN) {
343
344 /* timeout */
345
346 if (timer != NGX_TIMER_INFINITE) {
347 return NGX_AGAIN;
348 }
349
350 ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
351 "sigtimedwait() returned EAGAIN without timeout");
352 return NGX_ERROR;
353 }
354
355 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
356 cycle->log, err, "sigtimedwait() failed");
357 return NGX_ERROR;
358 }
359
360 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
361 "rtsig signo:%d fd:%d band:%04Xd",
362 signo, si.si_fd, si.si_band);
363
364 if (flags & NGX_UPDATE_TIME) {
365 ngx_time_update();
366 }
367
368 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
369
370 if (signo == (int) rtscf->signo || signo == (int) rtscf->signo + 1) {
371
372 if (overflow && (ngx_uint_t) si.si_fd > overflow_current) {
373 return NGX_OK;
374 }
375
376 c = ngx_cycle->files[si.si_fd];
377
378 if (c == NULL) {
379
380 /* the stale event */
381
382 return NGX_OK;
383 }
384
385 instance = signo - (int) rtscf->signo;
386
387 rev = c->read;
388
389 if (rev->instance != instance) {
390
391 /*
392 * the stale event from a file descriptor
393 * that was just closed in this iteration
394 */
395
396 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
397 "rtsig: stale event %p", c);
398
399 return NGX_OK;
400 }
401
402 if ((si.si_band & (POLLIN|POLLHUP|POLLERR)) && rev->active) {
403
404 rev->ready = 1;
405
406 if (flags & NGX_POST_EVENTS) {
407 queue = rev->accept ? &ngx_posted_accept_events
408 : &ngx_posted_events;
409
410 ngx_post_event(rev, queue);
411
412 } else {
413 rev->handler(rev);
414 }
415 }
416
417 wev = c->write;
418
419 if ((si.si_band & (POLLOUT|POLLHUP|POLLERR)) && wev->active) {
420
421 wev->ready = 1;
422
423 if (flags & NGX_POST_EVENTS) {
424 ngx_post_event(wev, &ngx_posted_events);
425
426 } else {
427 wev->handler(wev);
428 }
429 }
430
431 return NGX_OK;
432
433 } else if (signo == SIGALRM) {
434
435 ngx_time_update();
436
437 return NGX_OK;
438
439 } else if (signo == SIGIO) {
440
441 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
442 "rt signal queue overflowed");
443
444 /* flush the RT signal queue */
445
446 ngx_memzero(&sa, sizeof(struct sigaction));
447 sa.sa_handler = SIG_DFL;
448 sigemptyset(&sa.sa_mask);
449
450 if (sigaction(rtscf->signo, &sa, NULL) == -1) {
451 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
452 "sigaction(%d, SIG_DFL) failed", rtscf->signo);
453 }
454
455 if (sigaction(rtscf->signo + 1, &sa, NULL) == -1) {
456 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
457 "sigaction(%d, SIG_DFL) failed", rtscf->signo + 1);
458 }
459
460 overflow = 1;
461 overflow_current = 0;
462 ngx_event_actions.process_events = ngx_rtsig_process_overflow;
463
464 return NGX_ERROR;
465
466 }
467
468 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
469 "sigtimedwait() returned unexpected signal: %d", signo);
470
471 return NGX_ERROR;
472 }
473
474
475 static ngx_int_t
476 ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
477 ngx_uint_t flags)
478 {
479 int name[2], rtsig_max, rtsig_nr, events, ready;
480 size_t len;
481 ngx_err_t err;
482 ngx_uint_t tested, n, i;
483 ngx_event_t *rev, *wev;
484 ngx_queue_t *queue;
485 ngx_connection_t *c;
486 ngx_rtsig_conf_t *rtscf;
487
488 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
489 "rtsig process overflow");
490
491 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
492
493 tested = 0;
494
495 for ( ;; ) {
496
497 n = 0;
498 while (n < rtscf->overflow_events) {
499
500 if (overflow_current == cycle->connection_n) {
501 break;
502 }
503
504 c = cycle->files[overflow_current++];
505
506 if (c == NULL || c->fd == -1) {
507 continue;
508 }
509
510 events = 0;
511
512 if (c->read->active && c->read->handler) {
513 events |= POLLIN;
514 }
515
516 if (c->write->active && c->write->handler) {
517 events |= POLLOUT;
518 }
519
520 if (events == 0) {
521 continue;
522 }
523
524 overflow_list[n].fd = c->fd;
525 overflow_list[n].events = events;
526 overflow_list[n].revents = 0;
527 n++;
528 }
529
530 if (n == 0) {
531 break;
532 }
533
534 for ( ;; ) {
535 ready = poll(overflow_list, n, 0);
536
537 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
538 "rtsig overflow poll:%d", ready);
539
540 if (ready == -1) {
541 err = ngx_errno;
542 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
543 cycle->log, 0,
544 "poll() failed while the overflow recover");
545
546 if (err == NGX_EINTR) {
547 continue;
548 }
549 }
550
551 break;
552 }
553
554 if (ready <= 0) {
555 continue;
556 }
557
558 for (i = 0; i < n; i++) {
559 c = cycle->files[overflow_list[i].fd];
560
561 if (c == NULL) {
562 continue;
563 }
564
565 rev = c->read;
566
567 if (rev->active
568 && !rev->closed
569 && rev->handler
570 && (overflow_list[i].revents
571 & (POLLIN|POLLERR|POLLHUP|POLLNVAL)))
572 {
573 tested++;
574
575 rev->ready = 1;
576
577 if (flags & NGX_POST_EVENTS) {
578 queue = rev->accept ? &ngx_posted_accept_events
579 : &ngx_posted_events;
580
581 ngx_post_event(rev, queue);
582
583 } else {
584 rev->handler(rev);
585 }
586 }
587
588 wev = c->write;
589
590 if (wev->active
591 && !wev->closed
592 && wev->handler
593 && (overflow_list[i].revents
594 & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)))
595 {
596 tested++;
597
598 wev->ready = 1;
599
600 if (flags & NGX_POST_EVENTS) {
601 ngx_post_event(wev, &ngx_posted_events);
602
603 } else {
604 wev->handler(wev);
605 }
606 }
607 }
608
609 if (tested >= rtscf->overflow_test) {
610
611 if (ngx_linux_rtsig_max) {
612
613 /*
614 * Check the current rt queue length to prevent
615 * the new overflow.
616 *
617 * learn the "/proc/sys/kernel/rtsig-max" value because
618 * it can be changed since the last checking
619 */
620
621 name[0] = CTL_KERN;
622 name[1] = KERN_RTSIGMAX;
623 len = sizeof(rtsig_max);
624
625 if (sysctl(name, 2, &rtsig_max, &len, NULL, 0) == -1) {
626 ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
627 "sysctl(KERN_RTSIGMAX) failed");
628 return NGX_ERROR;
629 }
630
631 /* name[0] = CTL_KERN; */
632 name[1] = KERN_RTSIGNR;
633 len = sizeof(rtsig_nr);
634
635 if (sysctl(name, 2, &rtsig_nr, &len, NULL, 0) == -1) {
636 ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
637 "sysctl(KERN_RTSIGNR) failed");
638 return NGX_ERROR;
639 }
640
641 /*
642 * drain the rt signal queue if the /"proc/sys/kernel/rtsig-nr"
643 * is bigger than
644 * "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold"
645 */
646
647 if (rtsig_max / (int) rtscf->overflow_threshold < rtsig_nr) {
648 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
649 "rtsig queue state: %d/%d",
650 rtsig_nr, rtsig_max);
651 while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK)
652 {
653 /* void */
654 }
655 }
656
657 } else {
658
659 /*
660 * Linux has not KERN_RTSIGMAX since 2.6.6-mm2
661 * so drain the rt signal queue unconditionally
662 */
663
664 while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK) {
665 /* void */
666 }
667 }
668
669 tested = 0;
670 }
671 }
672
673 if (flags & NGX_UPDATE_TIME) {
674 ngx_time_update();
675 }
676
677 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
678 "rt signal queue overflow recovered");
679
680 overflow = 0;
681 ngx_event_actions.process_events = ngx_rtsig_process_events;
682
683 return NGX_OK;
684 }
685
686
687 static void *
688 ngx_rtsig_create_conf(ngx_cycle_t *cycle)
689 {
690 ngx_rtsig_conf_t *rtscf;
691
692 rtscf = ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t));
693 if (rtscf == NULL) {
694 return NULL;
695 }
696
697 rtscf->signo = NGX_CONF_UNSET;
698 rtscf->overflow_events = NGX_CONF_UNSET;
699 rtscf->overflow_test = NGX_CONF_UNSET;
700 rtscf->overflow_threshold = NGX_CONF_UNSET;
701
702 return rtscf;
703 }
704
705
706 static char *
707 ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf)
708 {
709 ngx_rtsig_conf_t *rtscf = conf;
710
711 /* LinuxThreads use the first 3 RT signals */
712 ngx_conf_init_uint_value(rtscf->signo, SIGRTMIN + 10);
713
714 ngx_conf_init_uint_value(rtscf->overflow_events, 16);
715 ngx_conf_init_uint_value(rtscf->overflow_test, 32);
716 ngx_conf_init_uint_value(rtscf->overflow_threshold, 10);
717
718 return NGX_CONF_OK;
719 }
720
721
722 static char *
723 ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, void *post, void *data)
724 {
725 if (ngx_linux_rtsig_max) {
726 return ngx_conf_check_num_bounds(cf, post, data);
727 }
728
729 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
730 "\"rtsig_overflow_threshold\" is not supported "
731 "since Linux 2.6.6-mm2, ignored");
732
733 return NGX_CONF_OK;
734 }
1616 extern ngx_module_t ngx_eventport_module;
1717 extern ngx_module_t ngx_devpoll_module;
1818 extern ngx_module_t ngx_epoll_module;
19 extern ngx_module_t ngx_rtsig_module;
2019 extern ngx_module_t ngx_select_module;
2120
2221
329328 }
330329 }
331330
332 /* iocp, rtsig */
331 /* iocp */
333332
334333 return NGX_OK;
335334 }
408407 }
409408 }
410409
411 /* iocp, rtsig */
410 /* iocp */
412411
413412 return NGX_OK;
414413 }
816815 continue;
817816 }
818817
819 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
820 if (ngx_add_conn(c) == NGX_ERROR) {
821 return NGX_ERROR;
822 }
823
824 } else {
825 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
826 return NGX_ERROR;
827 }
818 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
819 return NGX_ERROR;
828820 }
829821
830822 #endif
11901182 #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
11911183 int fd;
11921184 #endif
1193 #if (NGX_HAVE_RTSIG)
1194 ngx_uint_t rtsig;
1195 ngx_core_conf_t *ccf;
1196 #endif
11971185 ngx_int_t i;
11981186 ngx_module_t *module;
11991187 ngx_event_module_t *event_module;
12141202
12151203 #endif
12161204
1217 #if (NGX_HAVE_RTSIG)
1218
1219 if (module == NULL) {
1220 module = &ngx_rtsig_module;
1221 rtsig = 1;
1222
1223 } else {
1224 rtsig = 0;
1225 }
1226
1227 #endif
1228
12291205 #if (NGX_HAVE_DEVPOLL)
12301206
12311207 module = &ngx_devpoll_module;
12821258 ngx_conf_init_value(ecf->accept_mutex, 1);
12831259 ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
12841260
1285
1286 #if (NGX_HAVE_RTSIG)
1287
1288 if (!rtsig) {
1289 return NGX_CONF_OK;
1290 }
1291
1292 if (ecf->accept_mutex) {
1293 return NGX_CONF_OK;
1294 }
1295
1296 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
1297
1298 if (ccf->worker_processes == 0) {
1299 return NGX_CONF_OK;
1300 }
1301
1302 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
1303 "the \"rtsig\" method requires \"accept_mutex\" to be on");
1304
1305 return NGX_CONF_ERROR;
1306
1307 #else
1308
13091261 return NGX_CONF_OK;
1310
1311 #endif
1312 }
1262 }
3333
3434 unsigned accept:1;
3535
36 /* used to detect the stale events in kqueue, rtsig, and epoll */
36 /* used to detect the stale events in kqueue and epoll */
3737 unsigned instance:1;
3838
3939 /*
229229 #define NGX_USE_LOWAT_EVENT 0x00000010
230230
231231 /*
232 * The event filter requires to do i/o operation until EAGAIN: epoll, rtsig.
232 * The event filter requires to do i/o operation until EAGAIN: epoll.
233233 */
234234 #define NGX_USE_GREEDY_EVENT 0x00000020
235235
239239 #define NGX_USE_EPOLL_EVENT 0x00000040
240240
241241 /*
242 * No need to add or delete the event filters: rtsig.
242 * Obsolete.
243243 */
244244 #define NGX_USE_RTSIG_EVENT 0x00000080
245245
255255
256256 /*
257257 * The event filter has no opaque data and requires file descriptors table:
258 * poll, /dev/poll, rtsig.
258 * poll, /dev/poll.
259259 */
260260 #define NGX_USE_FD_EVENT 0x00000400
261261
280280 /*
281281 * The event filter is deleted just before the closing file.
282282 * Has no meaning for select and poll.
283 * kqueue, epoll, rtsig, eventport: allows to avoid explicit delete,
283 * kqueue, epoll, eventport: allows to avoid explicit delete,
284284 * because filter automatically is deleted
285285 * on file close,
286286 *
4141
4242 ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
4343
44 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
45 ev->available = 1;
46
47 } else if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
44 if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
4845 ev->available = ecf->multi_accept;
4946 }
5047
188185 }
189186
190187 } else {
191 if (!(ngx_event_flags & (NGX_USE_IOCP_EVENT|NGX_USE_RTSIG_EVENT))) {
188 if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
192189 if (ngx_nonblocking(s) == -1) {
193190 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
194191 ngx_nonblocking_n " failed");
231228
232229 wev->ready = 1;
233230
234 if (ngx_event_flags & (NGX_USE_IOCP_EVENT|NGX_USE_RTSIG_EVENT)) {
231 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
235232 rev->ready = 1;
236233 }
237234
373370 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
374371 "accept mutex locked");
375372
376 if (ngx_accept_mutex_held
377 && ngx_accept_events == 0
378 && !(ngx_event_flags & NGX_USE_RTSIG_EVENT))
379 {
373 if (ngx_accept_mutex_held && ngx_accept_events == 0) {
380374 return NGX_OK;
381375 }
382376
422416 continue;
423417 }
424418
425 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
426
427 if (ngx_add_conn(c) == NGX_ERROR) {
428 return NGX_ERROR;
429 }
430
431 } else {
432 if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) {
433 return NGX_ERROR;
434 }
419 if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) {
420 return NGX_ERROR;
435421 }
436422 }
437423
455441 continue;
456442 }
457443
458 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
459 if (ngx_del_conn(c, NGX_DISABLE_EVENT) == NGX_ERROR) {
460 return NGX_ERROR;
461 }
462
463 } else {
464 if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT)
465 == NGX_ERROR)
466 {
467 return NGX_ERROR;
468 }
444 if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT)
445 == NGX_ERROR)
446 {
447 return NGX_ERROR;
469448 }
470449 }
471450
348348 }
349349
350350 if (rev->ready) {
351 /* the deferred accept(), rtsig, iocp */
351 /* the deferred accept(), iocp */
352352
353353 if (ngx_use_accept_mutex) {
354354 ngx_post_event(rev, &ngx_posted_events);
1111 ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
1212 off_t limit);
1313
14 extern int ngx_linux_rtsig_max;
15
1614
1715 #endif /* _NGX_LINUX_H_INCLUDED_ */
8181 #endif
8282
8383
84 #if (NGX_HAVE_RTSIG)
85 #include <poll.h>
86 #include <sys/sysctl.h>
87 #endif
88
89
9084 #if (NGX_HAVE_EPOLL)
9185 #include <sys/epoll.h>
9286 #endif
1010
1111 u_char ngx_linux_kern_ostype[50];
1212 u_char ngx_linux_kern_osrelease[50];
13
14 int ngx_linux_rtsig_max;
1513
1614
1715 static ngx_os_io_t ngx_linux_io = {
4543 (void) ngx_cpystrn(ngx_linux_kern_osrelease, (u_char *) u.release,
4644 sizeof(ngx_linux_kern_osrelease));
4745
48 #if (NGX_HAVE_RTSIG)
49 {
50 int name[2];
51 size_t len;
52 ngx_err_t err;
53
54 name[0] = CTL_KERN;
55 name[1] = KERN_RTSIGMAX;
56 len = sizeof(ngx_linux_rtsig_max);
57
58 if (sysctl(name, 2, &ngx_linux_rtsig_max, &len, NULL, 0) == -1) {
59 err = ngx_errno;
60
61 if (err != NGX_ENOTDIR && err != NGX_ENOSYS) {
62 ngx_log_error(NGX_LOG_ALERT, log, err,
63 "sysctl(KERN_RTSIGMAX) failed");
64
65 return NGX_ERROR;
66 }
67
68 ngx_linux_rtsig_max = 0;
69 }
70
71 }
72 #endif
73
7446 ngx_os_io = ngx_linux_io;
7547
7648 return NGX_OK;
8254 {
8355 ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
8456 ngx_linux_kern_ostype, ngx_linux_kern_osrelease);
85
86 #if (NGX_HAVE_RTSIG)
87 ngx_log_error(NGX_LOG_NOTICE, log, 0, "sysctl(KERN_RTSIGMAX): %d",
88 ngx_linux_rtsig_max);
89 #endif
9057 }