Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 1 | |
| 2 | /* |
Igor Sysoev | ff8da91 | 2004-09-29 16:00:49 +0000 | [diff] [blame] | 3 | * Copyright (C) Igor Sysoev |
Maxim Konovalov | f8d59e3 | 2012-01-18 15:07:43 +0000 | [diff] [blame] | 4 | * Copyright (C) Nginx, Inc. |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | |
| 8 | #include <ngx_config.h> |
| 9 | #include <ngx_core.h> |
| 10 | #include <ngx_event.h> |
| 11 | |
| 12 | |
Igor Sysoev | f690604 | 2004-11-25 16:17:31 +0000 | [diff] [blame] | 13 | #if (NGX_TEST_BUILD_RTSIG) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 14 | |
Ruslan Ermilov | 1efcca3 | 2012-07-24 15:09:54 +0000 | [diff] [blame] | 15 | #if (NGX_DARWIN) |
| 16 | |
| 17 | #define SIGRTMIN 33 |
| 18 | #define si_fd __pad[0] |
| 19 | |
| 20 | #else |
| 21 | |
Igor Sysoev | b9186ad | 2008-03-13 15:47:14 +0000 | [diff] [blame] | 22 | #ifdef SIGRTMIN |
Igor Sysoev | 6e8bc2b | 2008-01-28 16:24:01 +0000 | [diff] [blame] | 23 | #define si_fd _reason.__spare__.__spare2__[0] |
Igor Sysoev | b9186ad | 2008-03-13 15:47:14 +0000 | [diff] [blame] | 24 | #else |
| 25 | #define SIGRTMIN 33 |
| 26 | #define si_fd __spare__[0] |
| 27 | #endif |
| 28 | |
Ruslan Ermilov | 1efcca3 | 2012-07-24 15:09:54 +0000 | [diff] [blame] | 29 | #endif |
| 30 | |
Igor Sysoev | b9186ad | 2008-03-13 15:47:14 +0000 | [diff] [blame] | 31 | #define F_SETSIG 10 |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 32 | #define KERN_RTSIGNR 30 |
| 33 | #define KERN_RTSIGMAX 31 |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 34 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 35 | int sigtimedwait(const sigset_t *set, siginfo_t *info, |
Ruslan Ermilov | 1efcca3 | 2012-07-24 15:09:54 +0000 | [diff] [blame] | 36 | const struct timespec *timeout); |
| 37 | |
| 38 | int sigtimedwait(const sigset_t *set, siginfo_t *info, |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 39 | const struct timespec *timeout) |
| 40 | { |
| 41 | return -1; |
| 42 | } |
| 43 | |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 44 | int ngx_linux_rtsig_max; |
| 45 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 46 | #endif |
| 47 | |
| 48 | |
| 49 | typedef struct { |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 50 | ngx_uint_t signo; |
| 51 | ngx_uint_t overflow_events; |
| 52 | ngx_uint_t overflow_test; |
| 53 | ngx_uint_t overflow_threshold; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 54 | } ngx_rtsig_conf_t; |
| 55 | |
| 56 | |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 57 | extern ngx_event_module_t ngx_poll_module_ctx; |
| 58 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 59 | static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 60 | static void ngx_rtsig_done(ngx_cycle_t *cycle); |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 61 | static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c); |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 62 | static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, |
| 63 | ngx_uint_t flags); |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 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); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 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); |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 71 | static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 72 | void *post, void *data); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 73 | |
| 74 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 75 | static sigset_t set; |
| 76 | static ngx_uint_t overflow, overflow_current; |
| 77 | static struct pollfd *overflow_list; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 78 | |
| 79 | |
| 80 | static ngx_str_t rtsig_name = ngx_string("rtsig"); |
| 81 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 82 | static ngx_conf_num_bounds_t ngx_overflow_threshold_bounds = { |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 83 | ngx_check_ngx_overflow_threshold_bounds, 2, 10 |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 84 | }; |
| 85 | |
| 86 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 87 | static ngx_command_t ngx_rtsig_commands[] = { |
| 88 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 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 }, |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 95 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 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 }, |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 102 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 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 }, |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 109 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 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 }, |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 116 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 117 | ngx_null_command |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 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 */ |
Igor Sysoev | c78c41c | 2004-07-07 06:15:04 +0000 | [diff] [blame] | 133 | NULL, /* process the changes */ |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 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 = { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 142 | NGX_MODULE_V1, |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 143 | &ngx_rtsig_module_ctx, /* module context */ |
| 144 | ngx_rtsig_commands, /* module directives */ |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 145 | NGX_EVENT_MODULE, /* module type */ |
Igor Sysoev | e573380 | 2005-09-08 14:36:09 +0000 | [diff] [blame] | 146 | NULL, /* init master */ |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 147 | NULL, /* init module */ |
Igor Sysoev | e573380 | 2005-09-08 14:36:09 +0000 | [diff] [blame] | 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 |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 154 | }; |
| 155 | |
| 156 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 157 | static ngx_int_t |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 158 | ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 159 | { |
| 160 | ngx_rtsig_conf_t *rtscf; |
| 161 | |
| 162 | rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module); |
| 163 | |
| 164 | sigemptyset(&set); |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 165 | sigaddset(&set, (int) rtscf->signo); |
| 166 | sigaddset(&set, (int) rtscf->signo + 1); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 167 | sigaddset(&set, SIGIO); |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 168 | sigaddset(&set, SIGALRM); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 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 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 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 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 186 | ngx_io = ngx_os_io; |
| 187 | |
| 188 | ngx_event_actions = ngx_rtsig_module_ctx.actions; |
| 189 | |
Igor Sysoev | 31eb8c0 | 2005-09-23 11:02:22 +0000 | [diff] [blame] | 190 | ngx_event_flags = NGX_USE_RTSIG_EVENT |
| 191 | |NGX_USE_GREEDY_EVENT |
| 192 | |NGX_USE_FD_EVENT; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 193 | |
| 194 | return NGX_OK; |
| 195 | } |
| 196 | |
| 197 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 198 | static void |
| 199 | ngx_rtsig_done(ngx_cycle_t *cycle) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 200 | { |
Igor Sysoev | 924bd79 | 2004-10-11 15:07:03 +0000 | [diff] [blame] | 201 | ngx_free(overflow_list); |
| 202 | |
| 203 | overflow_list = NULL; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 204 | } |
| 205 | |
| 206 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 207 | static ngx_int_t |
| 208 | ngx_rtsig_add_connection(ngx_connection_t *c) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 209 | { |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 210 | ngx_uint_t signo; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 211 | ngx_rtsig_conf_t *rtscf; |
| 212 | |
Igor Sysoev | 956ae65 | 2004-06-09 16:36:55 +0000 | [diff] [blame] | 213 | if (c->read->accept && c->read->disabled) { |
Igor Sysoev | 87350f2 | 2004-06-15 07:55:11 +0000 | [diff] [blame] | 214 | |
| 215 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
| 216 | "rtsig enable connection: fd:%d", c->fd); |
| 217 | |
Igor Sysoev | 956ae65 | 2004-06-09 16:36:55 +0000 | [diff] [blame] | 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 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 228 | rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); |
| 229 | |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 230 | signo = rtscf->signo + c->read->instance; |
| 231 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 232 | ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 233 | "rtsig add connection: fd:%d signo:%ui", c->fd, signo); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 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 | |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 241 | if (fcntl(c->fd, F_SETSIG, (int) signo) == -1) { |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 242 | ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, |
| 243 | "fcntl(F_SETSIG) failed"); |
| 244 | return NGX_ERROR; |
| 245 | } |
| 246 | |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 247 | if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) { |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 248 | ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, |
| 249 | "fcntl(F_SETOWN) failed"); |
| 250 | return NGX_ERROR; |
| 251 | } |
| 252 | |
Igor Sysoev | f690604 | 2004-11-25 16:17:31 +0000 | [diff] [blame] | 253 | #if (NGX_HAVE_ONESIGFD) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 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 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 268 | static ngx_int_t |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 269 | ngx_rtsig_del_connection(ngx_connection_t *c, ngx_uint_t flags) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 270 | { |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 271 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
| 272 | "rtsig del connection: fd:%d", c->fd); |
| 273 | |
Igor Sysoev | 956ae65 | 2004-06-09 16:36:55 +0000 | [diff] [blame] | 274 | if ((flags & NGX_DISABLE_EVENT) && c->read->accept) { |
Igor Sysoev | 87350f2 | 2004-06-15 07:55:11 +0000 | [diff] [blame] | 275 | |
| 276 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
| 277 | "rtsig disable connection: fd:%d", c->fd); |
| 278 | |
Igor Sysoev | 956ae65 | 2004-06-09 16:36:55 +0000 | [diff] [blame] | 279 | c->read->active = 0; |
Igor Sysoev | 87350f2 | 2004-06-15 07:55:11 +0000 | [diff] [blame] | 280 | c->read->disabled = 1; |
Igor Sysoev | 956ae65 | 2004-06-09 16:36:55 +0000 | [diff] [blame] | 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; |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 294 | } |
| 295 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 296 | c->read->active = 0; |
| 297 | c->write->active = 0; |
| 298 | |
| 299 | return NGX_OK; |
| 300 | } |
| 301 | |
| 302 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 303 | static ngx_int_t |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 304 | ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 305 | { |
| 306 | int signo; |
Igor Sysoev | c157172 | 2005-03-19 12:38:37 +0000 | [diff] [blame] | 307 | ngx_int_t instance; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 308 | ngx_err_t err; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 309 | siginfo_t si; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 310 | ngx_event_t *rev, *wev, **queue; |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 311 | struct timespec ts, *tp; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 312 | struct sigaction sa; |
Igor Sysoev | cccc552 | 2004-04-14 20:34:05 +0000 | [diff] [blame] | 313 | ngx_connection_t *c; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 314 | ngx_rtsig_conf_t *rtscf; |
| 315 | |
Igor Sysoev | cccc552 | 2004-04-14 20:34:05 +0000 | [diff] [blame] | 316 | if (timer == NGX_TIMER_INFINITE) { |
| 317 | tp = NULL; |
Igor Sysoev | cccc552 | 2004-04-14 20:34:05 +0000 | [diff] [blame] | 318 | |
| 319 | } else { |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 320 | ts.tv_sec = timer / 1000; |
| 321 | ts.tv_nsec = (timer % 1000) * 1000000; |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 322 | tp = &ts; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 323 | } |
| 324 | |
Igor Sysoev | c972a3f | 2004-04-02 15:13:20 +0000 | [diff] [blame] | 325 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
Igor Sysoev | 208eed2 | 2005-10-07 13:30:52 +0000 | [diff] [blame] | 326 | "rtsig timer: %M", timer); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 327 | |
Igor Sysoev | 2b97993 | 2004-07-07 15:01:00 +0000 | [diff] [blame] | 328 | /* Linux's sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */ |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 329 | |
| 330 | signo = sigtimedwait(&set, &si, tp); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 331 | |
| 332 | if (signo == -1) { |
| 333 | err = ngx_errno; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 334 | |
Igor Sysoev | 8e811c1 | 2004-07-07 19:48:31 +0000 | [diff] [blame] | 335 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err, |
| 336 | "rtsig signo:%d", signo); |
| 337 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 338 | if (flags & NGX_UPDATE_TIME) { |
Igor Sysoev | 6d45d8a | 2010-03-25 09:10:10 +0000 | [diff] [blame] | 339 | ngx_time_update(); |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 340 | } |
| 341 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 342 | if (err == NGX_EAGAIN) { |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 343 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 344 | /* timeout */ |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 345 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 346 | if (timer != NGX_TIMER_INFINITE) { |
| 347 | return NGX_AGAIN; |
| 348 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 349 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 350 | ngx_log_error(NGX_LOG_ALERT, cycle->log, err, |
| 351 | "sigtimedwait() returned EAGAIN without timeout"); |
| 352 | return NGX_ERROR; |
| 353 | } |
| 354 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 355 | ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, |
Igor Sysoev | c972a3f | 2004-04-02 15:13:20 +0000 | [diff] [blame] | 356 | cycle->log, err, "sigtimedwait() failed"); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 357 | return NGX_ERROR; |
| 358 | } |
| 359 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 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); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 363 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 364 | if (flags & NGX_UPDATE_TIME) { |
Igor Sysoev | 6d45d8a | 2010-03-25 09:10:10 +0000 | [diff] [blame] | 365 | ngx_time_update(); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 366 | } |
| 367 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 368 | rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); |
| 369 | |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 370 | if (signo == (int) rtscf->signo || signo == (int) rtscf->signo + 1) { |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 371 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 372 | if (overflow && (ngx_uint_t) si.si_fd > overflow_current) { |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 373 | return NGX_OK; |
| 374 | } |
| 375 | |
Igor Sysoev | 31eb8c0 | 2005-09-23 11:02:22 +0000 | [diff] [blame] | 376 | c = ngx_cycle->files[si.si_fd]; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 377 | |
Igor Sysoev | 82dc95e | 2005-10-03 12:53:14 +0000 | [diff] [blame] | 378 | if (c == NULL) { |
Igor Sysoev | 82dc95e | 2005-10-03 12:53:14 +0000 | [diff] [blame] | 379 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 380 | /* the stale event */ |
Igor Sysoev | 82dc95e | 2005-10-03 12:53:14 +0000 | [diff] [blame] | 381 | |
| 382 | return NGX_OK; |
| 383 | } |
| 384 | |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 385 | instance = signo - (int) rtscf->signo; |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 386 | |
Igor Sysoev | 2b97993 | 2004-07-07 15:01:00 +0000 | [diff] [blame] | 387 | rev = c->read; |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 388 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 389 | if (rev->instance != instance) { |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 390 | |
| 391 | /* |
| 392 | * the stale event from a file descriptor |
| 393 | * that was just closed in this iteration |
| 394 | */ |
| 395 | |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 396 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
Igor Sysoev | 1b73583 | 2004-11-11 14:07:14 +0000 | [diff] [blame] | 397 | "rtsig: stale event %p", c); |
Igor Sysoev | 67f450d | 2004-06-01 06:04:46 +0000 | [diff] [blame] | 398 | |
| 399 | return NGX_OK; |
| 400 | } |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 401 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 402 | if ((si.si_band & (POLLIN|POLLHUP|POLLERR)) && rev->active) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 403 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 404 | rev->ready = 1; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 405 | |
| 406 | if (flags & NGX_POST_EVENTS) { |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 407 | queue = rev->accept ? &ngx_posted_accept_events |
| 408 | : &ngx_posted_events; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 409 | |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 410 | ngx_post_event(rev, queue); |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 411 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 412 | } else { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 413 | rev->handler(rev); |
| 414 | } |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 415 | } |
| 416 | |
Igor Sysoev | 2b97993 | 2004-07-07 15:01:00 +0000 | [diff] [blame] | 417 | wev = c->write; |
| 418 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 419 | if ((si.si_band & (POLLOUT|POLLHUP|POLLERR)) && wev->active) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 420 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 421 | wev->ready = 1; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 422 | |
| 423 | if (flags & NGX_POST_EVENTS) { |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 424 | ngx_post_event(wev, &ngx_posted_events); |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 425 | |
| 426 | } else { |
| 427 | wev->handler(wev); |
| 428 | } |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 429 | } |
| 430 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 431 | return NGX_OK; |
| 432 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 433 | } else if (signo == SIGALRM) { |
| 434 | |
Igor Sysoev | 6d45d8a | 2010-03-25 09:10:10 +0000 | [diff] [blame] | 435 | ngx_time_update(); |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 436 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 437 | return NGX_OK; |
| 438 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 439 | } else if (signo == SIGIO) { |
Igor Sysoev | cccc552 | 2004-04-14 20:34:05 +0000 | [diff] [blame] | 440 | |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 441 | ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
| 442 | "rt signal queue overflowed"); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 443 | |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 444 | /* flush the RT signal queue */ |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 445 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 446 | ngx_memzero(&sa, sizeof(struct sigaction)); |
| 447 | sa.sa_handler = SIG_DFL; |
| 448 | sigemptyset(&sa.sa_mask); |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 449 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 450 | if (sigaction(rtscf->signo, &sa, NULL) == -1) { |
Igor Sysoev | c972a3f | 2004-04-02 15:13:20 +0000 | [diff] [blame] | 451 | ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 452 | "sigaction(%d, SIG_DFL) failed", rtscf->signo); |
| 453 | } |
| 454 | |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 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; |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 461 | overflow_current = 0; |
Igor Sysoev | c78c41c | 2004-07-07 06:15:04 +0000 | [diff] [blame] | 462 | ngx_event_actions.process_events = ngx_rtsig_process_overflow; |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 463 | |
Igor Sysoev | d962b61 | 2004-06-11 06:15:08 +0000 | [diff] [blame] | 464 | return NGX_ERROR; |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 465 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 466 | } |
| 467 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 468 | ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
| 469 | "sigtimedwait() returned unexpected signal: %d", signo); |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 470 | |
Igor Sysoev | 055951d | 2005-10-21 19:12:18 +0000 | [diff] [blame] | 471 | return NGX_ERROR; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 472 | } |
| 473 | |
| 474 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 475 | static ngx_int_t |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 476 | ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer, |
| 477 | ngx_uint_t flags) |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 478 | { |
Igor Sysoev | 87350f2 | 2004-06-15 07:55:11 +0000 | [diff] [blame] | 479 | int name[2], rtsig_max, rtsig_nr, events, ready; |
| 480 | size_t len; |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 481 | ngx_err_t err; |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 482 | ngx_uint_t tested, n, i; |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 483 | ngx_event_t *rev, *wev, **queue; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 484 | ngx_connection_t *c; |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 485 | ngx_rtsig_conf_t *rtscf; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 486 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 487 | ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
| 488 | "rtsig process overflow"); |
| 489 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 490 | rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 491 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 492 | tested = 0; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 493 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 494 | for ( ;; ) { |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 495 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 496 | n = 0; |
| 497 | while (n < rtscf->overflow_events) { |
| 498 | |
| 499 | if (overflow_current == cycle->connection_n) { |
| 500 | break; |
| 501 | } |
| 502 | |
Igor Sysoev | 31eb8c0 | 2005-09-23 11:02:22 +0000 | [diff] [blame] | 503 | c = cycle->files[overflow_current++]; |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 504 | |
Igor Sysoev | 1bfa7bc | 2005-10-10 12:59:41 +0000 | [diff] [blame] | 505 | if (c == NULL || c->fd == -1) { |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 506 | continue; |
| 507 | } |
| 508 | |
| 509 | events = 0; |
| 510 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 511 | if (c->read->active && c->read->handler) { |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 512 | events |= POLLIN; |
| 513 | } |
| 514 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 515 | if (c->write->active && c->write->handler) { |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 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 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 536 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
| 537 | "rtsig overflow poll:%d", ready); |
| 538 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 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 | |
Igor Sysoev | 5ec68f6 | 2004-07-28 16:16:50 +0000 | [diff] [blame] | 545 | if (err == NGX_EINTR) { |
| 546 | continue; |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 547 | } |
| 548 | } |
Igor Sysoev | 5ec68f6 | 2004-07-28 16:16:50 +0000 | [diff] [blame] | 549 | |
| 550 | break; |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 551 | } |
| 552 | |
| 553 | if (ready <= 0) { |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 554 | continue; |
| 555 | } |
| 556 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 557 | for (i = 0; i < n; i++) { |
Igor Sysoev | 31eb8c0 | 2005-09-23 11:02:22 +0000 | [diff] [blame] | 558 | c = cycle->files[overflow_list[i].fd]; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 559 | |
Igor Sysoev | 1bfa7bc | 2005-10-10 12:59:41 +0000 | [diff] [blame] | 560 | if (c == NULL) { |
| 561 | continue; |
| 562 | } |
| 563 | |
Igor Sysoev | 2b97993 | 2004-07-07 15:01:00 +0000 | [diff] [blame] | 564 | rev = c->read; |
| 565 | |
Igor Sysoev | 846c27b | 2004-07-13 20:24:56 +0000 | [diff] [blame] | 566 | if (rev->active |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 567 | && !rev->closed |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 568 | && rev->handler |
Igor Sysoev | 846c27b | 2004-07-13 20:24:56 +0000 | [diff] [blame] | 569 | && (overflow_list[i].revents |
| 570 | & (POLLIN|POLLERR|POLLHUP|POLLNVAL))) |
| 571 | { |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 572 | tested++; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 573 | |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 574 | rev->ready = 1; |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 575 | |
| 576 | if (flags & NGX_POST_EVENTS) { |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 577 | queue = rev->accept ? &ngx_posted_accept_events |
| 578 | : &ngx_posted_events; |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 579 | |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 580 | ngx_post_event(rev, queue); |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 581 | |
| 582 | } else { |
| 583 | rev->handler(rev); |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 584 | } |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 585 | } |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 586 | |
Igor Sysoev | 2b97993 | 2004-07-07 15:01:00 +0000 | [diff] [blame] | 587 | wev = c->write; |
| 588 | |
Igor Sysoev | 846c27b | 2004-07-13 20:24:56 +0000 | [diff] [blame] | 589 | if (wev->active |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 590 | && !wev->closed |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 591 | && wev->handler |
Igor Sysoev | 846c27b | 2004-07-13 20:24:56 +0000 | [diff] [blame] | 592 | && (overflow_list[i].revents |
| 593 | & (POLLOUT|POLLERR|POLLHUP|POLLNVAL))) |
| 594 | { |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 595 | tested++; |
Igor Sysoev | 2b97993 | 2004-07-07 15:01:00 +0000 | [diff] [blame] | 596 | |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 597 | wev->ready = 1; |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 598 | |
| 599 | if (flags & NGX_POST_EVENTS) { |
Valentin Bartenev | 2a81e05 | 2014-09-01 18:20:03 +0400 | [diff] [blame^] | 600 | ngx_post_event(wev, &ngx_posted_events); |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 601 | |
| 602 | } else { |
| 603 | wev->handler(wev); |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 604 | } |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 605 | } |
| 606 | } |
| 607 | |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 608 | if (tested >= rtscf->overflow_test) { |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 609 | |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 610 | if (ngx_linux_rtsig_max) { |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 611 | |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 612 | /* |
| 613 | * Check the current rt queue length to prevent |
| 614 | * the new overflow. |
| 615 | * |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 616 | * learn the "/proc/sys/kernel/rtsig-max" value because |
| 617 | * it can be changed since the last checking |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 618 | */ |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 619 | |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 620 | name[0] = CTL_KERN; |
| 621 | name[1] = KERN_RTSIGMAX; |
| 622 | len = sizeof(rtsig_max); |
Igor Sysoev | d039a2e | 2005-02-22 14:40:13 +0000 | [diff] [blame] | 623 | |
| 624 | if (sysctl(name, 2, &rtsig_max, &len, NULL, 0) == -1) { |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 625 | ngx_log_error(NGX_LOG_ALERT, cycle->log, errno, |
| 626 | "sysctl(KERN_RTSIGMAX) failed"); |
| 627 | return NGX_ERROR; |
| 628 | } |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 629 | |
Igor Sysoev | d039a2e | 2005-02-22 14:40:13 +0000 | [diff] [blame] | 630 | /* name[0] = CTL_KERN; */ |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 631 | name[1] = KERN_RTSIGNR; |
| 632 | len = sizeof(rtsig_nr); |
Igor Sysoev | d039a2e | 2005-02-22 14:40:13 +0000 | [diff] [blame] | 633 | |
| 634 | if (sysctl(name, 2, &rtsig_nr, &len, NULL, 0) == -1) { |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 635 | ngx_log_error(NGX_LOG_ALERT, cycle->log, errno, |
| 636 | "sysctl(KERN_RTSIGNR) failed"); |
| 637 | return NGX_ERROR; |
| 638 | } |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 639 | |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 640 | /* |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 641 | * drain the rt signal queue if the /"proc/sys/kernel/rtsig-nr" |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 642 | * is bigger than |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 643 | * "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold" |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 644 | */ |
| 645 | |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 646 | if (rtsig_max / (int) rtscf->overflow_threshold < rtsig_nr) { |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 647 | ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
| 648 | "rtsig queue state: %d/%d", |
| 649 | rtsig_nr, rtsig_max); |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 650 | while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK) |
| 651 | { |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 652 | /* void */ |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | } else { |
| 657 | |
| 658 | /* |
| 659 | * Linux has not KERN_RTSIGMAX since 2.6.6-mm2 |
Igor Sysoev | 5ec68f6 | 2004-07-28 16:16:50 +0000 | [diff] [blame] | 660 | * so drain the rt signal queue unconditionally |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 661 | */ |
| 662 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 663 | while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK) { |
| 664 | /* void */ |
| 665 | } |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 666 | } |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 667 | |
| 668 | tested = 0; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 669 | } |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 670 | } |
| 671 | |
Igor Sysoev | c2068d0 | 2005-10-19 12:33:58 +0000 | [diff] [blame] | 672 | if (flags & NGX_UPDATE_TIME) { |
Igor Sysoev | 6d45d8a | 2010-03-25 09:10:10 +0000 | [diff] [blame] | 673 | ngx_time_update(); |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 674 | } |
| 675 | |
Igor Sysoev | 5192b36 | 2005-07-08 14:34:20 +0000 | [diff] [blame] | 676 | ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 677 | "rt signal queue overflow recovered"); |
| 678 | |
| 679 | overflow = 0; |
Igor Sysoev | c78c41c | 2004-07-07 06:15:04 +0000 | [diff] [blame] | 680 | ngx_event_actions.process_events = ngx_rtsig_process_events; |
Igor Sysoev | ebfd6c8 | 2004-06-09 07:45:27 +0000 | [diff] [blame] | 681 | |
Igor Sysoev | 22a7c50 | 2004-02-17 21:11:27 +0000 | [diff] [blame] | 682 | return NGX_OK; |
| 683 | } |
| 684 | |
| 685 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 686 | static void * |
| 687 | ngx_rtsig_create_conf(ngx_cycle_t *cycle) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 688 | { |
| 689 | ngx_rtsig_conf_t *rtscf; |
| 690 | |
Igor Sysoev | c157172 | 2005-03-19 12:38:37 +0000 | [diff] [blame] | 691 | rtscf = ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t)); |
| 692 | if (rtscf == NULL) { |
Igor Sysoev | 260c432 | 2009-06-02 16:09:44 +0000 | [diff] [blame] | 693 | return NULL; |
Igor Sysoev | c157172 | 2005-03-19 12:38:37 +0000 | [diff] [blame] | 694 | } |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 695 | |
| 696 | rtscf->signo = NGX_CONF_UNSET; |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 697 | rtscf->overflow_events = NGX_CONF_UNSET; |
| 698 | rtscf->overflow_test = NGX_CONF_UNSET; |
| 699 | rtscf->overflow_threshold = NGX_CONF_UNSET; |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 700 | |
| 701 | return rtscf; |
| 702 | } |
| 703 | |
| 704 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 705 | static char * |
| 706 | ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf) |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 707 | { |
| 708 | ngx_rtsig_conf_t *rtscf = conf; |
| 709 | |
| 710 | /* LinuxThreads use the first 3 RT signals */ |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 711 | ngx_conf_init_uint_value(rtscf->signo, SIGRTMIN + 10); |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 712 | |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 713 | ngx_conf_init_uint_value(rtscf->overflow_events, 16); |
| 714 | ngx_conf_init_uint_value(rtscf->overflow_test, 32); |
| 715 | ngx_conf_init_uint_value(rtscf->overflow_threshold, 10); |
Igor Sysoev | 0ed19cc | 2004-06-10 18:36:57 +0000 | [diff] [blame] | 716 | |
Igor Sysoev | 9139cd2 | 2004-02-17 17:53:12 +0000 | [diff] [blame] | 717 | return NGX_CONF_OK; |
| 718 | } |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 719 | |
| 720 | |
Igor Sysoev | 8184d1b | 2005-03-04 14:06:57 +0000 | [diff] [blame] | 721 | static char * |
Igor Sysoev | 83a6851 | 2007-07-29 18:24:53 +0000 | [diff] [blame] | 722 | ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, void *post, void *data) |
Igor Sysoev | 7823cc3 | 2004-07-14 16:01:42 +0000 | [diff] [blame] | 723 | { |
| 724 | if (ngx_linux_rtsig_max) { |
| 725 | return ngx_conf_check_num_bounds(cf, post, data); |
| 726 | } |
| 727 | |
| 728 | ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
| 729 | "\"rtsig_overflow_threshold\" is not supported " |
| 730 | "since Linux 2.6.6-mm2, ignored"); |
| 731 | |
| 732 | return NGX_CONF_OK; |
| 733 | } |