Annotation of embedaddon/nginx/src/event/modules/ngx_rtsig_module.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * Copyright (C) Igor Sysoev
! 4: * Copyright (C) Nginx, Inc.
! 5: */
! 6:
! 7:
! 8: #include <ngx_config.h>
! 9: #include <ngx_core.h>
! 10: #include <ngx_event.h>
! 11:
! 12:
! 13: #if (NGX_TEST_BUILD_RTSIG)
! 14:
! 15: #if (NGX_DARWIN)
! 16:
! 17: #define SIGRTMIN 33
! 18: #define si_fd __pad[0]
! 19:
! 20: #else
! 21:
! 22: #ifdef SIGRTMIN
! 23: #define si_fd _reason.__spare__.__spare2__[0]
! 24: #else
! 25: #define SIGRTMIN 33
! 26: #define si_fd __spare__[0]
! 27: #endif
! 28:
! 29: #endif
! 30:
! 31: #define F_SETSIG 10
! 32: #define KERN_RTSIGNR 30
! 33: #define KERN_RTSIGMAX 31
! 34:
! 35: int sigtimedwait(const sigset_t *set, siginfo_t *info,
! 36: const struct timespec *timeout);
! 37:
! 38: int sigtimedwait(const sigset_t *set, siginfo_t *info,
! 39: const struct timespec *timeout)
! 40: {
! 41: return -1;
! 42: }
! 43:
! 44: int ngx_linux_rtsig_max;
! 45:
! 46: #endif
! 47:
! 48:
! 49: typedef struct {
! 50: ngx_uint_t signo;
! 51: ngx_uint_t overflow_events;
! 52: ngx_uint_t overflow_test;
! 53: ngx_uint_t overflow_threshold;
! 54: } ngx_rtsig_conf_t;
! 55:
! 56:
! 57: extern ngx_event_module_t ngx_poll_module_ctx;
! 58:
! 59: static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer);
! 60: static void ngx_rtsig_done(ngx_cycle_t *cycle);
! 61: static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c);
! 62: static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c,
! 63: ngx_uint_t flags);
! 64: static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle,
! 65: ngx_msec_t timer, ngx_uint_t flags);
! 66: static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle,
! 67: ngx_msec_t timer, ngx_uint_t flags);
! 68:
! 69: static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle);
! 70: static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf);
! 71: static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf,
! 72: void *post, void *data);
! 73:
! 74:
! 75: static sigset_t set;
! 76: static ngx_uint_t overflow, overflow_current;
! 77: static struct pollfd *overflow_list;
! 78:
! 79:
! 80: static ngx_str_t rtsig_name = ngx_string("rtsig");
! 81:
! 82: static ngx_conf_num_bounds_t ngx_overflow_threshold_bounds = {
! 83: ngx_check_ngx_overflow_threshold_bounds, 2, 10
! 84: };
! 85:
! 86:
! 87: static ngx_command_t ngx_rtsig_commands[] = {
! 88:
! 89: { ngx_string("rtsig_signo"),
! 90: NGX_EVENT_CONF|NGX_CONF_TAKE1,
! 91: ngx_conf_set_num_slot,
! 92: 0,
! 93: offsetof(ngx_rtsig_conf_t, signo),
! 94: NULL },
! 95:
! 96: { ngx_string("rtsig_overflow_events"),
! 97: NGX_EVENT_CONF|NGX_CONF_TAKE1,
! 98: ngx_conf_set_num_slot,
! 99: 0,
! 100: offsetof(ngx_rtsig_conf_t, overflow_events),
! 101: NULL },
! 102:
! 103: { ngx_string("rtsig_overflow_test"),
! 104: NGX_EVENT_CONF|NGX_CONF_TAKE1,
! 105: ngx_conf_set_num_slot,
! 106: 0,
! 107: offsetof(ngx_rtsig_conf_t, overflow_test),
! 108: NULL },
! 109:
! 110: { ngx_string("rtsig_overflow_threshold"),
! 111: NGX_EVENT_CONF|NGX_CONF_TAKE1,
! 112: ngx_conf_set_num_slot,
! 113: 0,
! 114: offsetof(ngx_rtsig_conf_t, overflow_threshold),
! 115: &ngx_overflow_threshold_bounds },
! 116:
! 117: ngx_null_command
! 118: };
! 119:
! 120:
! 121: ngx_event_module_t ngx_rtsig_module_ctx = {
! 122: &rtsig_name,
! 123: ngx_rtsig_create_conf, /* create configuration */
! 124: ngx_rtsig_init_conf, /* init configuration */
! 125:
! 126: {
! 127: NULL, /* add an event */
! 128: NULL, /* delete an event */
! 129: NULL, /* enable an event */
! 130: NULL, /* disable an event */
! 131: ngx_rtsig_add_connection, /* add an connection */
! 132: ngx_rtsig_del_connection, /* delete an connection */
! 133: NULL, /* process the changes */
! 134: ngx_rtsig_process_events, /* process the events */
! 135: ngx_rtsig_init, /* init the events */
! 136: ngx_rtsig_done, /* done the events */
! 137: }
! 138:
! 139: };
! 140:
! 141: ngx_module_t ngx_rtsig_module = {
! 142: NGX_MODULE_V1,
! 143: &ngx_rtsig_module_ctx, /* module context */
! 144: ngx_rtsig_commands, /* module directives */
! 145: NGX_EVENT_MODULE, /* module type */
! 146: NULL, /* init master */
! 147: NULL, /* init module */
! 148: NULL, /* init process */
! 149: NULL, /* init thread */
! 150: NULL, /* exit thread */
! 151: NULL, /* exit process */
! 152: NULL, /* exit master */
! 153: NGX_MODULE_V1_PADDING
! 154: };
! 155:
! 156:
! 157: static ngx_int_t
! 158: ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer)
! 159: {
! 160: ngx_rtsig_conf_t *rtscf;
! 161:
! 162: rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
! 163:
! 164: sigemptyset(&set);
! 165: sigaddset(&set, (int) rtscf->signo);
! 166: sigaddset(&set, (int) rtscf->signo + 1);
! 167: sigaddset(&set, SIGIO);
! 168: sigaddset(&set, SIGALRM);
! 169:
! 170: if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
! 171: ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
! 172: "sigprocmask() failed");
! 173: return NGX_ERROR;
! 174: }
! 175:
! 176: if (overflow_list) {
! 177: ngx_free(overflow_list);
! 178: }
! 179:
! 180: overflow_list = ngx_alloc(sizeof(struct pollfd) * rtscf->overflow_events,
! 181: cycle->log);
! 182: if (overflow_list == NULL) {
! 183: return NGX_ERROR;
! 184: }
! 185:
! 186: ngx_io = ngx_os_io;
! 187:
! 188: ngx_event_actions = ngx_rtsig_module_ctx.actions;
! 189:
! 190: ngx_event_flags = NGX_USE_RTSIG_EVENT
! 191: |NGX_USE_GREEDY_EVENT
! 192: |NGX_USE_FD_EVENT;
! 193:
! 194: return NGX_OK;
! 195: }
! 196:
! 197:
! 198: static void
! 199: ngx_rtsig_done(ngx_cycle_t *cycle)
! 200: {
! 201: ngx_free(overflow_list);
! 202:
! 203: overflow_list = NULL;
! 204: }
! 205:
! 206:
! 207: static ngx_int_t
! 208: ngx_rtsig_add_connection(ngx_connection_t *c)
! 209: {
! 210: ngx_uint_t signo;
! 211: ngx_rtsig_conf_t *rtscf;
! 212:
! 213: if (c->read->accept && c->read->disabled) {
! 214:
! 215: ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
! 216: "rtsig enable connection: fd:%d", c->fd);
! 217:
! 218: if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
! 219: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
! 220: "fcntl(F_SETOWN) failed");
! 221: return NGX_ERROR;
! 222: }
! 223:
! 224: c->read->active = 1;
! 225: c->read->disabled = 0;
! 226: }
! 227:
! 228: rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
! 229:
! 230: signo = rtscf->signo + c->read->instance;
! 231:
! 232: ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
! 233: "rtsig add connection: fd:%d signo:%ui", c->fd, signo);
! 234:
! 235: if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) {
! 236: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
! 237: "fcntl(O_RDWR|O_NONBLOCK|O_ASYNC) failed");
! 238: return NGX_ERROR;
! 239: }
! 240:
! 241: if (fcntl(c->fd, F_SETSIG, (int) signo) == -1) {
! 242: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
! 243: "fcntl(F_SETSIG) failed");
! 244: return NGX_ERROR;
! 245: }
! 246:
! 247: if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
! 248: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
! 249: "fcntl(F_SETOWN) failed");
! 250: return NGX_ERROR;
! 251: }
! 252:
! 253: #if (NGX_HAVE_ONESIGFD)
! 254: if (fcntl(c->fd, F_SETAUXFL, O_ONESIGFD) == -1) {
! 255: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
! 256: "fcntl(F_SETAUXFL) failed");
! 257: return NGX_ERROR;
! 258: }
! 259: #endif
! 260:
! 261: c->read->active = 1;
! 262: c->write->active = 1;
! 263:
! 264: return NGX_OK;
! 265: }
! 266:
! 267:
! 268: static ngx_int_t
! 269: ngx_rtsig_del_connection(ngx_connection_t *c, ngx_uint_t flags)
! 270: {
! 271: ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
! 272: "rtsig del connection: fd:%d", c->fd);
! 273:
! 274: if ((flags & NGX_DISABLE_EVENT) && c->read->accept) {
! 275:
! 276: ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
! 277: "rtsig disable connection: fd:%d", c->fd);
! 278:
! 279: c->read->active = 0;
! 280: c->read->disabled = 1;
! 281: return NGX_OK;
! 282: }
! 283:
! 284: if (flags & NGX_CLOSE_EVENT) {
! 285: c->read->active = 0;
! 286: c->write->active = 0;
! 287: return NGX_OK;
! 288: }
! 289:
! 290: if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK) == -1) {
! 291: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
! 292: "fcntl(O_RDWR|O_NONBLOCK) failed");
! 293: return NGX_ERROR;
! 294: }
! 295:
! 296: c->read->active = 0;
! 297: c->write->active = 0;
! 298:
! 299: return NGX_OK;
! 300: }
! 301:
! 302:
! 303: static ngx_int_t
! 304: ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
! 305: {
! 306: int signo;
! 307: ngx_int_t instance;
! 308: ngx_err_t err;
! 309: siginfo_t si;
! 310: ngx_event_t *rev, *wev, **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 = (ngx_event_t **) (rev->accept ?
! 408: &ngx_posted_accept_events : &ngx_posted_events);
! 409:
! 410: ngx_locked_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_locked_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, **queue;
! 484: ngx_connection_t *c;
! 485: ngx_rtsig_conf_t *rtscf;
! 486:
! 487: ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
! 488: "rtsig process overflow");
! 489:
! 490: rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
! 491:
! 492: tested = 0;
! 493:
! 494: for ( ;; ) {
! 495:
! 496: n = 0;
! 497: while (n < rtscf->overflow_events) {
! 498:
! 499: if (overflow_current == cycle->connection_n) {
! 500: break;
! 501: }
! 502:
! 503: c = cycle->files[overflow_current++];
! 504:
! 505: if (c == NULL || c->fd == -1) {
! 506: continue;
! 507: }
! 508:
! 509: events = 0;
! 510:
! 511: if (c->read->active && c->read->handler) {
! 512: events |= POLLIN;
! 513: }
! 514:
! 515: if (c->write->active && c->write->handler) {
! 516: events |= POLLOUT;
! 517: }
! 518:
! 519: if (events == 0) {
! 520: continue;
! 521: }
! 522:
! 523: overflow_list[n].fd = c->fd;
! 524: overflow_list[n].events = events;
! 525: overflow_list[n].revents = 0;
! 526: n++;
! 527: }
! 528:
! 529: if (n == 0) {
! 530: break;
! 531: }
! 532:
! 533: for ( ;; ) {
! 534: ready = poll(overflow_list, n, 0);
! 535:
! 536: ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
! 537: "rtsig overflow poll:%d", ready);
! 538:
! 539: if (ready == -1) {
! 540: err = ngx_errno;
! 541: ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
! 542: cycle->log, 0,
! 543: "poll() failed while the overflow recover");
! 544:
! 545: if (err == NGX_EINTR) {
! 546: continue;
! 547: }
! 548: }
! 549:
! 550: break;
! 551: }
! 552:
! 553: if (ready <= 0) {
! 554: continue;
! 555: }
! 556:
! 557: ngx_mutex_lock(ngx_posted_events_mutex);
! 558:
! 559: for (i = 0; i < n; i++) {
! 560: c = cycle->files[overflow_list[i].fd];
! 561:
! 562: if (c == NULL) {
! 563: continue;
! 564: }
! 565:
! 566: rev = c->read;
! 567:
! 568: if (rev->active
! 569: && !rev->closed
! 570: && rev->handler
! 571: && (overflow_list[i].revents
! 572: & (POLLIN|POLLERR|POLLHUP|POLLNVAL)))
! 573: {
! 574: tested++;
! 575:
! 576: if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
! 577: rev->posted_ready = 1;
! 578:
! 579: } else {
! 580: rev->ready = 1;
! 581: }
! 582:
! 583: if (flags & NGX_POST_EVENTS) {
! 584: queue = (ngx_event_t **) (rev->accept ?
! 585: &ngx_posted_accept_events : &ngx_posted_events);
! 586:
! 587: ngx_locked_post_event(rev, queue);
! 588:
! 589: } else {
! 590: rev->handler(rev);
! 591: }
! 592: }
! 593:
! 594: wev = c->write;
! 595:
! 596: if (wev->active
! 597: && !wev->closed
! 598: && wev->handler
! 599: && (overflow_list[i].revents
! 600: & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)))
! 601: {
! 602: tested++;
! 603:
! 604: if (flags & NGX_POST_THREAD_EVENTS) {
! 605: wev->posted_ready = 1;
! 606:
! 607: } else {
! 608: wev->ready = 1;
! 609: }
! 610:
! 611: if (flags & NGX_POST_EVENTS) {
! 612: ngx_locked_post_event(wev, &ngx_posted_events);
! 613:
! 614: } else {
! 615: wev->handler(wev);
! 616: }
! 617: }
! 618: }
! 619:
! 620: ngx_mutex_unlock(ngx_posted_events_mutex);
! 621:
! 622: if (tested >= rtscf->overflow_test) {
! 623:
! 624: if (ngx_linux_rtsig_max) {
! 625:
! 626: /*
! 627: * Check the current rt queue length to prevent
! 628: * the new overflow.
! 629: *
! 630: * learn the "/proc/sys/kernel/rtsig-max" value because
! 631: * it can be changed since the last checking
! 632: */
! 633:
! 634: name[0] = CTL_KERN;
! 635: name[1] = KERN_RTSIGMAX;
! 636: len = sizeof(rtsig_max);
! 637:
! 638: if (sysctl(name, 2, &rtsig_max, &len, NULL, 0) == -1) {
! 639: ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
! 640: "sysctl(KERN_RTSIGMAX) failed");
! 641: return NGX_ERROR;
! 642: }
! 643:
! 644: /* name[0] = CTL_KERN; */
! 645: name[1] = KERN_RTSIGNR;
! 646: len = sizeof(rtsig_nr);
! 647:
! 648: if (sysctl(name, 2, &rtsig_nr, &len, NULL, 0) == -1) {
! 649: ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
! 650: "sysctl(KERN_RTSIGNR) failed");
! 651: return NGX_ERROR;
! 652: }
! 653:
! 654: /*
! 655: * drain the rt signal queue if the /"proc/sys/kernel/rtsig-nr"
! 656: * is bigger than
! 657: * "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold"
! 658: */
! 659:
! 660: if (rtsig_max / (int) rtscf->overflow_threshold < rtsig_nr) {
! 661: ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
! 662: "rtsig queue state: %d/%d",
! 663: rtsig_nr, rtsig_max);
! 664: while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK)
! 665: {
! 666: /* void */
! 667: }
! 668: }
! 669:
! 670: } else {
! 671:
! 672: /*
! 673: * Linux has not KERN_RTSIGMAX since 2.6.6-mm2
! 674: * so drain the rt signal queue unconditionally
! 675: */
! 676:
! 677: while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK) {
! 678: /* void */
! 679: }
! 680: }
! 681:
! 682: tested = 0;
! 683: }
! 684: }
! 685:
! 686: if (flags & NGX_UPDATE_TIME) {
! 687: ngx_time_update();
! 688: }
! 689:
! 690: ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
! 691: "rt signal queue overflow recovered");
! 692:
! 693: overflow = 0;
! 694: ngx_event_actions.process_events = ngx_rtsig_process_events;
! 695:
! 696: return NGX_OK;
! 697: }
! 698:
! 699:
! 700: static void *
! 701: ngx_rtsig_create_conf(ngx_cycle_t *cycle)
! 702: {
! 703: ngx_rtsig_conf_t *rtscf;
! 704:
! 705: rtscf = ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t));
! 706: if (rtscf == NULL) {
! 707: return NULL;
! 708: }
! 709:
! 710: rtscf->signo = NGX_CONF_UNSET;
! 711: rtscf->overflow_events = NGX_CONF_UNSET;
! 712: rtscf->overflow_test = NGX_CONF_UNSET;
! 713: rtscf->overflow_threshold = NGX_CONF_UNSET;
! 714:
! 715: return rtscf;
! 716: }
! 717:
! 718:
! 719: static char *
! 720: ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf)
! 721: {
! 722: ngx_rtsig_conf_t *rtscf = conf;
! 723:
! 724: /* LinuxThreads use the first 3 RT signals */
! 725: ngx_conf_init_uint_value(rtscf->signo, SIGRTMIN + 10);
! 726:
! 727: ngx_conf_init_uint_value(rtscf->overflow_events, 16);
! 728: ngx_conf_init_uint_value(rtscf->overflow_test, 32);
! 729: ngx_conf_init_uint_value(rtscf->overflow_threshold, 10);
! 730:
! 731: return NGX_CONF_OK;
! 732: }
! 733:
! 734:
! 735: static char *
! 736: ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, void *post, void *data)
! 737: {
! 738: if (ngx_linux_rtsig_max) {
! 739: return ngx_conf_check_num_bounds(cf, post, data);
! 740: }
! 741:
! 742: ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
! 743: "\"rtsig_overflow_threshold\" is not supported "
! 744: "since Linux 2.6.6-mm2, ignored");
! 745:
! 746: return NGX_CONF_OK;
! 747: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>