src/event/modules/ngx_rtsig_module.c - nginx-1.7.10

Global variables defined

Data types defined

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_event.h>


  8. #if (NGX_TEST_BUILD_RTSIG)

  9. #if (NGX_DARWIN)

  10. #define SIGRTMIN       33
  11. #define si_fd          __pad[0]

  12. #else

  13. #ifdef  SIGRTMIN
  14. #define si_fd          _reason.__spare__.__spare2__[0]
  15. #else
  16. #define SIGRTMIN       33
  17. #define si_fd          __spare__[0]
  18. #endif

  19. #endif

  20. #define F_SETSIG       10
  21. #define KERN_RTSIGNR   30
  22. #define KERN_RTSIGMAX  31

  23. int sigtimedwait(const sigset_t *set, siginfo_t *info,
  24.                  const struct timespec *timeout);

  25. int sigtimedwait(const sigset_t *set, siginfo_t *info,
  26.                  const struct timespec *timeout)
  27. {
  28.     return -1;
  29. }

  30. int ngx_linux_rtsig_max;

  31. #endif


  32. typedef struct {
  33.     ngx_uint_t  signo;
  34.     ngx_uint_t  overflow_events;
  35.     ngx_uint_t  overflow_test;
  36.     ngx_uint_t  overflow_threshold;
  37. } ngx_rtsig_conf_t;


  38. extern ngx_event_module_t  ngx_poll_module_ctx;

  39. static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer);
  40. static void ngx_rtsig_done(ngx_cycle_t *cycle);
  41. static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c);
  42. static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c,
  43.     ngx_uint_t flags);
  44. static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle,
  45.     ngx_msec_t timer, ngx_uint_t flags);
  46. static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle,
  47.     ngx_msec_t timer, ngx_uint_t flags);

  48. static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle);
  49. static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf);
  50. static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf,
  51.     void *post, void *data);


  52. static sigset_t        set;
  53. static ngx_uint_t      overflow, overflow_current;
  54. static struct pollfd  *overflow_list;


  55. static ngx_str_t      rtsig_name = ngx_string("rtsig");

  56. static ngx_conf_num_bounds_t  ngx_overflow_threshold_bounds = {
  57.     ngx_check_ngx_overflow_threshold_bounds, 2, 10
  58. };


  59. static ngx_command_t  ngx_rtsig_commands[] = {

  60.     { ngx_string("rtsig_signo"),
  61.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  62.       ngx_conf_set_num_slot,
  63.       0,
  64.       offsetof(ngx_rtsig_conf_t, signo),
  65.       NULL },

  66.     { ngx_string("rtsig_overflow_events"),
  67.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  68.       ngx_conf_set_num_slot,
  69.       0,
  70.       offsetof(ngx_rtsig_conf_t, overflow_events),
  71.       NULL },

  72.     { ngx_string("rtsig_overflow_test"),
  73.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  74.       ngx_conf_set_num_slot,
  75.       0,
  76.       offsetof(ngx_rtsig_conf_t, overflow_test),
  77.       NULL },

  78.     { ngx_string("rtsig_overflow_threshold"),
  79.       NGX_EVENT_CONF|NGX_CONF_TAKE1,
  80.       ngx_conf_set_num_slot,
  81.       0,
  82.       offsetof(ngx_rtsig_conf_t, overflow_threshold),
  83.       &ngx_overflow_threshold_bounds },

  84.       ngx_null_command
  85. };


  86. ngx_event_module_t  ngx_rtsig_module_ctx = {
  87.     &rtsig_name,
  88.     ngx_rtsig_create_conf,               /* create configuration */
  89.     ngx_rtsig_init_conf,                 /* init configuration */

  90.     {
  91.         NULL,                            /* add an event */
  92.         NULL,                            /* delete an event */
  93.         NULL,                            /* enable an event */
  94.         NULL,                            /* disable an event */
  95.         ngx_rtsig_add_connection,        /* add an connection */
  96.         ngx_rtsig_del_connection,        /* delete an connection */
  97.         NULL,                            /* process the changes */
  98.         ngx_rtsig_process_events,        /* process the events */
  99.         ngx_rtsig_init,                  /* init the events */
  100.         ngx_rtsig_done,                  /* done the events */
  101.     }

  102. };

  103. ngx_module_t  ngx_rtsig_module = {
  104.     NGX_MODULE_V1,
  105.     &ngx_rtsig_module_ctx,               /* module context */
  106.     ngx_rtsig_commands,                  /* module directives */
  107.     NGX_EVENT_MODULE,                    /* module type */
  108.     NULL,                                /* init master */
  109.     NULL,                                /* init module */
  110.     NULL,                                /* init process */
  111.     NULL,                                /* init thread */
  112.     NULL,                                /* exit thread */
  113.     NULL,                                /* exit process */
  114.     NULL,                                /* exit master */
  115.     NGX_MODULE_V1_PADDING
  116. };


  117. static ngx_int_t
  118. ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer)
  119. {
  120.     ngx_rtsig_conf_t  *rtscf;

  121.     rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);

  122.     sigemptyset(&set);
  123.     sigaddset(&set, (int) rtscf->signo);
  124.     sigaddset(&set, (int) rtscf->signo + 1);
  125.     sigaddset(&set, SIGIO);
  126.     sigaddset(&set, SIGALRM);

  127.     if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
  128.         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  129.                       "sigprocmask() failed");
  130.         return NGX_ERROR;
  131.     }

  132.     if (overflow_list) {
  133.         ngx_free(overflow_list);
  134.     }

  135.     overflow_list = ngx_alloc(sizeof(struct pollfd) * rtscf->overflow_events,
  136.                               cycle->log);
  137.     if (overflow_list == NULL) {
  138.         return NGX_ERROR;
  139.     }

  140.     ngx_io = ngx_os_io;

  141.     ngx_event_actions = ngx_rtsig_module_ctx.actions;

  142.     ngx_event_flags = NGX_USE_RTSIG_EVENT
  143.                       |NGX_USE_GREEDY_EVENT
  144.                       |NGX_USE_FD_EVENT;

  145.     return NGX_OK;
  146. }


  147. static void
  148. ngx_rtsig_done(ngx_cycle_t *cycle)
  149. {
  150.     ngx_free(overflow_list);

  151.     overflow_list = NULL;
  152. }


  153. static ngx_int_t
  154. ngx_rtsig_add_connection(ngx_connection_t *c)
  155. {
  156.     ngx_uint_t         signo;
  157.     ngx_rtsig_conf_t  *rtscf;

  158.     if (c->read->accept && c->read->disabled) {

  159.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  160.                        "rtsig enable connection: fd:%d", c->fd);

  161.         if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
  162.             ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
  163.                           "fcntl(F_SETOWN) failed");
  164.             return NGX_ERROR;
  165.         }

  166.         c->read->active = 1;
  167.         c->read->disabled = 0;
  168.     }

  169.     rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);

  170.     signo = rtscf->signo + c->read->instance;

  171.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  172.                    "rtsig add connection: fd:%d signo:%ui", c->fd, signo);

  173.     if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) {
  174.         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
  175.                       "fcntl(O_RDWR|O_NONBLOCK|O_ASYNC) failed");
  176.         return NGX_ERROR;
  177.     }

  178.     if (fcntl(c->fd, F_SETSIG, (int) signo) == -1) {
  179.         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
  180.                       "fcntl(F_SETSIG) failed");
  181.         return NGX_ERROR;
  182.     }

  183.     if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
  184.         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
  185.                       "fcntl(F_SETOWN) failed");
  186.         return NGX_ERROR;
  187.     }

  188. #if (NGX_HAVE_ONESIGFD)
  189.     if (fcntl(c->fd, F_SETAUXFL, O_ONESIGFD) == -1) {
  190.         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
  191.                       "fcntl(F_SETAUXFL) failed");
  192.         return NGX_ERROR;
  193.     }
  194. #endif

  195.     c->read->active = 1;
  196.     c->write->active = 1;

  197.     return NGX_OK;
  198. }


  199. static ngx_int_t
  200. ngx_rtsig_del_connection(ngx_connection_t *c, ngx_uint_t flags)
  201. {
  202.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  203.                    "rtsig del connection: fd:%d", c->fd);

  204.     if ((flags & NGX_DISABLE_EVENT) && c->read->accept) {

  205.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  206.                        "rtsig disable connection: fd:%d", c->fd);

  207.         c->read->active = 0;
  208.         c->read->disabled = 1;
  209.         return NGX_OK;
  210.     }

  211.     if (flags & NGX_CLOSE_EVENT) {
  212.         c->read->active = 0;
  213.         c->write->active = 0;
  214.         return NGX_OK;
  215.     }

  216.     if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK) == -1) {
  217.         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
  218.                       "fcntl(O_RDWR|O_NONBLOCK) failed");
  219.         return NGX_ERROR;
  220.     }

  221.     c->read->active = 0;
  222.     c->write->active = 0;

  223.     return NGX_OK;
  224. }


  225. static ngx_int_t
  226. ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
  227. {
  228.     int                 signo;
  229.     ngx_int_t           instance;
  230.     ngx_err_t           err;
  231.     siginfo_t           si;
  232.     ngx_event_t        *rev, *wev;
  233.     ngx_queue_t        *queue;
  234.     struct timespec     ts, *tp;
  235.     struct sigaction    sa;
  236.     ngx_connection_t   *c;
  237.     ngx_rtsig_conf_t   *rtscf;

  238.     if (timer == NGX_TIMER_INFINITE) {
  239.         tp = NULL;

  240.     } else {
  241.         ts.tv_sec = timer / 1000;
  242.         ts.tv_nsec = (timer % 1000) * 1000000;
  243.         tp = &ts;
  244.     }

  245.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  246.                    "rtsig timer: %M", timer);

  247.     /* Linux's sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */

  248.     signo = sigtimedwait(&set, &si, tp);

  249.     if (signo == -1) {
  250.         err = ngx_errno;

  251.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
  252.                        "rtsig signo:%d", signo);

  253.         if (flags & NGX_UPDATE_TIME) {
  254.             ngx_time_update();
  255.         }

  256.         if (err == NGX_EAGAIN) {

  257.             /* timeout */

  258.             if (timer != NGX_TIMER_INFINITE) {
  259.                 return NGX_AGAIN;
  260.             }

  261.             ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
  262.                           "sigtimedwait() returned EAGAIN without timeout");
  263.             return NGX_ERROR;
  264.         }

  265.         ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
  266.                       cycle->log, err, "sigtimedwait() failed");
  267.         return NGX_ERROR;
  268.     }

  269.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  270.                    "rtsig signo:%d fd:%d band:%04Xd",
  271.                    signo, si.si_fd, si.si_band);

  272.     if (flags & NGX_UPDATE_TIME) {
  273.         ngx_time_update();
  274.     }

  275.     rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);

  276.     if (signo == (int) rtscf->signo || signo == (int) rtscf->signo + 1) {

  277.         if (overflow && (ngx_uint_t) si.si_fd > overflow_current) {
  278.             return NGX_OK;
  279.         }

  280.         c = ngx_cycle->files[si.si_fd];

  281.         if (c == NULL) {

  282.             /* the stale event */

  283.             return NGX_OK;
  284.         }

  285.         instance = signo - (int) rtscf->signo;

  286.         rev = c->read;

  287.         if (rev->instance != instance) {

  288.             /*
  289.              * the stale event from a file descriptor
  290.              * that was just closed in this iteration
  291.              */

  292.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  293.                            "rtsig: stale event %p", c);

  294.             return NGX_OK;
  295.         }

  296.         if ((si.si_band & (POLLIN|POLLHUP|POLLERR)) && rev->active) {

  297.             rev->ready = 1;

  298.             if (flags & NGX_POST_EVENTS) {
  299.                 queue = rev->accept ? &ngx_posted_accept_events
  300.                                     : &ngx_posted_events;

  301.                 ngx_post_event(rev, queue);

  302.             } else {
  303.                 rev->handler(rev);
  304.             }
  305.         }

  306.         wev = c->write;

  307.         if ((si.si_band & (POLLOUT|POLLHUP|POLLERR)) && wev->active) {

  308.             wev->ready = 1;

  309.             if (flags & NGX_POST_EVENTS) {
  310.                 ngx_post_event(wev, &ngx_posted_events);

  311.             } else {
  312.                 wev->handler(wev);
  313.             }
  314.         }

  315.         return NGX_OK;

  316.     } else if (signo == SIGALRM) {

  317.         ngx_time_update();

  318.         return NGX_OK;

  319.     } else if (signo == SIGIO) {

  320.         ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
  321.                       "rt signal queue overflowed");

  322.         /* flush the RT signal queue */

  323.         ngx_memzero(&sa, sizeof(struct sigaction));
  324.         sa.sa_handler = SIG_DFL;
  325.         sigemptyset(&sa.sa_mask);

  326.         if (sigaction(rtscf->signo, &sa, NULL) == -1) {
  327.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  328.                           "sigaction(%d, SIG_DFL) failed", rtscf->signo);
  329.         }

  330.         if (sigaction(rtscf->signo + 1, &sa, NULL) == -1) {
  331.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
  332.                           "sigaction(%d, SIG_DFL) failed", rtscf->signo + 1);
  333.         }

  334.         overflow = 1;
  335.         overflow_current = 0;
  336.         ngx_event_actions.process_events = ngx_rtsig_process_overflow;

  337.         return NGX_ERROR;

  338.     }

  339.     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
  340.                   "sigtimedwait() returned unexpected signal: %d", signo);

  341.     return NGX_ERROR;
  342. }


  343. static ngx_int_t
  344. ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
  345.     ngx_uint_t flags)
  346. {
  347.     int                name[2], rtsig_max, rtsig_nr, events, ready;
  348.     size_t             len;
  349.     ngx_err_t          err;
  350.     ngx_uint_t         tested, n, i;
  351.     ngx_event_t       *rev, *wev;
  352.     ngx_queue_t       *queue;
  353.     ngx_connection_t  *c;
  354.     ngx_rtsig_conf_t  *rtscf;

  355.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  356.                    "rtsig process overflow");

  357.     rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);

  358.     tested = 0;

  359.     for ( ;; ) {

  360.         n = 0;
  361.         while (n < rtscf->overflow_events) {

  362.             if (overflow_current == cycle->connection_n) {
  363.                 break;
  364.             }

  365.             c = cycle->files[overflow_current++];

  366.             if (c == NULL || c->fd == -1) {
  367.                 continue;
  368.             }

  369.             events = 0;

  370.             if (c->read->active && c->read->handler) {
  371.                 events |= POLLIN;
  372.             }

  373.             if (c->write->active && c->write->handler) {
  374.                 events |= POLLOUT;
  375.             }

  376.             if (events == 0) {
  377.                 continue;
  378.             }

  379.             overflow_list[n].fd = c->fd;
  380.             overflow_list[n].events = events;
  381.             overflow_list[n].revents = 0;
  382.             n++;
  383.         }

  384.         if (n == 0) {
  385.             break;
  386.         }

  387.         for ( ;; ) {
  388.             ready = poll(overflow_list, n, 0);

  389.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  390.                            "rtsig overflow poll:%d", ready);

  391.             if (ready == -1) {
  392.                 err = ngx_errno;
  393.                 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
  394.                               cycle->log, 0,
  395.                               "poll() failed while the overflow recover");

  396.                 if (err == NGX_EINTR) {
  397.                     continue;
  398.                 }
  399.             }

  400.             break;
  401.         }

  402.         if (ready <= 0) {
  403.             continue;
  404.         }

  405.         for (i = 0; i < n; i++) {
  406.             c = cycle->files[overflow_list[i].fd];

  407.             if (c == NULL) {
  408.                 continue;
  409.             }

  410.             rev = c->read;

  411.             if (rev->active
  412.                 && !rev->closed
  413.                 && rev->handler
  414.                 && (overflow_list[i].revents
  415.                                           & (POLLIN|POLLERR|POLLHUP|POLLNVAL)))
  416.             {
  417.                 tested++;

  418.                 rev->ready = 1;

  419.                 if (flags & NGX_POST_EVENTS) {
  420.                     queue = rev->accept ? &ngx_posted_accept_events
  421.                                         : &ngx_posted_events;

  422.                     ngx_post_event(rev, queue);

  423.                 } else {
  424.                     rev->handler(rev);
  425.                 }
  426.             }

  427.             wev = c->write;

  428.             if (wev->active
  429.                 && !wev->closed
  430.                 && wev->handler
  431.                 && (overflow_list[i].revents
  432.                                          & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)))
  433.             {
  434.                 tested++;

  435.                 wev->ready = 1;

  436.                 if (flags & NGX_POST_EVENTS) {
  437.                     ngx_post_event(wev, &ngx_posted_events);

  438.                 } else {
  439.                     wev->handler(wev);
  440.                 }
  441.             }
  442.         }

  443.         if (tested >= rtscf->overflow_test) {

  444.             if (ngx_linux_rtsig_max) {

  445.                 /*
  446.                  * Check the current rt queue length to prevent
  447.                  * the new overflow.
  448.                  *
  449.                  * learn the "/proc/sys/kernel/rtsig-max" value because
  450.                  * it can be changed since the last checking
  451.                  */

  452.                 name[0] = CTL_KERN;
  453.                 name[1] = KERN_RTSIGMAX;
  454.                 len = sizeof(rtsig_max);

  455.                 if (sysctl(name, 2, &rtsig_max, &len, NULL, 0) == -1) {
  456.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
  457.                                   "sysctl(KERN_RTSIGMAX) failed");
  458.                     return NGX_ERROR;
  459.                 }

  460.                 /* name[0] = CTL_KERN; */
  461.                 name[1] = KERN_RTSIGNR;
  462.                 len = sizeof(rtsig_nr);

  463.                 if (sysctl(name, 2, &rtsig_nr, &len, NULL, 0) == -1) {
  464.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
  465.                                   "sysctl(KERN_RTSIGNR) failed");
  466.                     return NGX_ERROR;
  467.                 }

  468.                 /*
  469.                  * drain the rt signal queue if the /"proc/sys/kernel/rtsig-nr"
  470.                  * is bigger than
  471.                  *    "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold"
  472.                  */

  473.                 if (rtsig_max / (int) rtscf->overflow_threshold < rtsig_nr) {
  474.                     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
  475.                                    "rtsig queue state: %d/%d",
  476.                                    rtsig_nr, rtsig_max);
  477.                     while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK)
  478.                     {
  479.                         /* void */
  480.                     }
  481.                 }

  482.             } else {

  483.                 /*
  484.                  * Linux has not KERN_RTSIGMAX since 2.6.6-mm2
  485.                  * so drain the rt signal queue unconditionally
  486.                  */

  487.                 while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK) {
  488.                     /* void */
  489.                 }
  490.             }

  491.             tested = 0;
  492.         }
  493.     }

  494.     if (flags & NGX_UPDATE_TIME) {
  495.         ngx_time_update();
  496.     }

  497.     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
  498.                   "rt signal queue overflow recovered");

  499.     overflow = 0;
  500.     ngx_event_actions.process_events = ngx_rtsig_process_events;

  501.     return NGX_OK;
  502. }


  503. static void *
  504. ngx_rtsig_create_conf(ngx_cycle_t *cycle)
  505. {
  506.     ngx_rtsig_conf_t  *rtscf;

  507.     rtscf = ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t));
  508.     if (rtscf == NULL) {
  509.         return NULL;
  510.     }

  511.     rtscf->signo = NGX_CONF_UNSET;
  512.     rtscf->overflow_events = NGX_CONF_UNSET;
  513.     rtscf->overflow_test = NGX_CONF_UNSET;
  514.     rtscf->overflow_threshold = NGX_CONF_UNSET;

  515.     return rtscf;
  516. }


  517. static char *
  518. ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf)
  519. {
  520.     ngx_rtsig_conf_t  *rtscf = conf;

  521.     /* LinuxThreads use the first 3 RT signals */
  522.     ngx_conf_init_uint_value(rtscf->signo, SIGRTMIN + 10);

  523.     ngx_conf_init_uint_value(rtscf->overflow_events, 16);
  524.     ngx_conf_init_uint_value(rtscf->overflow_test, 32);
  525.     ngx_conf_init_uint_value(rtscf->overflow_threshold, 10);

  526.     return NGX_CONF_OK;
  527. }


  528. static char *
  529. ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, void *post, void *data)
  530. {
  531.     if (ngx_linux_rtsig_max) {
  532.         return ngx_conf_check_num_bounds(cf, post, data);
  533.     }

  534.     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  535.                        "\"rtsig_overflow_threshold\" is not supported "
  536.                        "since Linux 2.6.6-mm2, ignored");

  537.     return NGX_CONF_OK;
  538. }