Klaus Demo nginx / 4524fb0
Solaris 10 event ports support Igor Sysoev 15 years ago
9 changed file(s) with 683 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
2828 have=NGX_TEST_BUILD_DEVPOLL . auto/have
2929 EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
3030 CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
31 fi
32
33
34 if [ $NGX_TEST_BUILD_EVENTPORT = YES ]; then
35 have=NGX_HAVE_EVENTPORT . auto/have
36 have=NGX_TEST_BUILD_EVENTPORT . auto/have
37 EVENT_MODULES="$EVENT_MODULES $EVENTPORT_MODULE"
38 CORE_SRCS="$CORE_SRCS $EVENTPORT_SRCS"
3139 fi
3240
3341 if [ $NGX_TEST_BUILD_EPOLL = YES ]; then
2222 CPU=NO
2323
2424 NGX_TEST_BUILD_DEVPOLL=NO
25 NGX_TEST_BUILD_EVENTPORT=NO
2526 NGX_TEST_BUILD_EPOLL=NO
2627 NGX_TEST_BUILD_RTSIG=NO
2728 NGX_TEST_BUILD_SOLARIS_SENDFILEV=NO
206207 --with-zlib-asm=*) ZLIB_ASM="$value" ;;
207208
208209 --test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;;
210 --test-build-eventport) NGX_TEST_BUILD_EVENTPORT=YES ;;
209211 --test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;;
210212 --test-build-rtsig) NGX_TEST_BUILD_RTSIG=YES ;;
211213 --test-build-solaris-sendfilev) NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;;
3838 CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS"
3939 CORE_LIBS="$CORE_LIBS -lsendfile"
4040 fi
41
42
43 ngx_feature="event ports"
44 ngx_feature_name="NGX_HAVE_EVENTPORT"
45 ngx_feature_run=no
46 ngx_feature_incs="#include <port.h>"
47 ngx_feature_libs=
48 ngx_feature_test="int n = port_create()"
49 . auto/feature
50
51 if [ $ngx_found = yes ]; then
52 CORE_SRCS="$CORE_SRCS $EVENTPORT_SRCS"
53 EVENT_MODULES="$EVENT_MODULES $EVENTPORT_MODULE"
54 fi
9494 DEVPOLL_MODULE=ngx_devpoll_module
9595 DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c
9696
97 EVENTPORT_MODULE=ngx_eventport_module
98 EVENTPORT_SRCS=src/event/modules/ngx_eventport_module.c
99
97100 EPOLL_MODULE=ngx_epoll_module
98101 EPOLL_SRCS=src/event/modules/ngx_epoll_module.c
99102
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_event.h>
9
10
11 #if (NGX_TEST_BUILD_EVENTPORT)
12
13 #define ushort_t u_short
14 #define uint_t u_int
15
16 /* Solaris declarations */
17
18 #define PORT_SOURCE_AIO 1
19 #define PORT_SOURCE_TIMER 2
20 #define PORT_SOURCE_USER 3
21 #define PORT_SOURCE_FD 4
22 #define PORT_SOURCE_ALERT 5
23 #define PORT_SOURCE_MQ 6
24
25 #define ETIME 64
26
27 #define SIGEV_PORT 4
28
29 typedef struct {
30 int portev_events; /* event data is source specific */
31 ushort_t portev_source; /* event source */
32 ushort_t portev_pad; /* port internal use */
33 uintptr_t portev_object; /* source specific object */
34 void *portev_user; /* user cookie */
35 } port_event_t;
36
37 typedef struct port_notify {
38 int portnfy_port; /* bind request(s) to port */
39 void *portnfy_user; /* user defined */
40 } port_notify_t;
41
42 typedef struct itimerspec { /* definition per POSIX.4 */
43 struct timespec it_interval; /* timer period */
44 struct timespec it_value; /* timer expiration */
45 } itimerspec_t;
46
47 int port_create(void)
48 {
49 return -1;
50 }
51
52 int port_associate(int port, int source, uintptr_t object, int events,
53 void *user)
54 {
55 return -1;
56 }
57
58 int port_dissociate(int port, int source, uintptr_t object)
59 {
60 return -1;
61 }
62
63 int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
64 struct timespec *timeout)
65 {
66 return -1;
67 }
68
69 int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
70 {
71 return -1;
72 }
73
74 int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
75 struct itimerspec *ovalue)
76 {
77 return -1;
78 }
79
80 int timer_delete(timer_t timerid)
81 {
82 return -1;
83 }
84
85 #endif
86
87
88 typedef struct {
89 u_int events;
90 } ngx_eventport_conf_t;
91
92
93 static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer);
94 static void ngx_eventport_done(ngx_cycle_t *cycle);
95 static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, int event,
96 u_int flags);
97 static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, int event,
98 u_int flags);
99 static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle,
100 ngx_msec_t timer, ngx_uint_t flags);
101
102 static void *ngx_eventport_create_conf(ngx_cycle_t *cycle);
103 static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf);
104
105 static int ep = -1;
106 static port_event_t *event_list;
107 static u_int nevents;
108 static timer_t event_timer = -1;
109
110 static ngx_str_t eventport_name = ngx_string("eventport");
111
112
113 static ngx_command_t ngx_eventport_commands[] = {
114
115 { ngx_string("eventport_events"),
116 NGX_EVENT_CONF|NGX_CONF_TAKE1,
117 ngx_conf_set_num_slot,
118 0,
119 offsetof(ngx_eventport_conf_t, events),
120 NULL },
121
122 ngx_null_command
123 };
124
125
126 ngx_event_module_t ngx_eventport_module_ctx = {
127 &eventport_name,
128 ngx_eventport_create_conf, /* create configuration */
129 ngx_eventport_init_conf, /* init configuration */
130
131 {
132 ngx_eventport_add_event, /* add an event */
133 ngx_eventport_del_event, /* delete an event */
134 ngx_eventport_add_event, /* enable an event */
135 ngx_eventport_del_event, /* disable an event */
136 NULL, /* add an connection */
137 NULL, /* delete an connection */
138 NULL, /* process the changes */
139 ngx_eventport_process_events, /* process the events */
140 ngx_eventport_init, /* init the events */
141 ngx_eventport_done, /* done the events */
142 }
143
144 };
145
146 ngx_module_t ngx_eventport_module = {
147 NGX_MODULE_V1,
148 &ngx_eventport_module_ctx, /* module context */
149 ngx_eventport_commands, /* module directives */
150 NGX_EVENT_MODULE, /* module type */
151 NULL, /* init master */
152 NULL, /* init module */
153 NULL, /* init process */
154 NULL, /* init thread */
155 NULL, /* exit thread */
156 NULL, /* exit process */
157 NULL, /* exit master */
158 NGX_MODULE_V1_PADDING
159 };
160
161
162 static ngx_int_t
163 ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer)
164 {
165 port_notify_t pn;
166 struct itimerspec its;
167 struct sigevent sev;
168 ngx_eventport_conf_t *epcf;
169
170 epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_eventport_module);
171
172 if (ep == -1) {
173 ep = port_create();
174
175 if (ep == -1) {
176 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
177 "port_create() failed");
178 return NGX_ERROR;
179 }
180 }
181
182 if (nevents < epcf->events) {
183 if (event_list) {
184 ngx_free(event_list);
185 }
186
187 event_list = ngx_alloc(sizeof(port_event_t) * epcf->events,
188 cycle->log);
189 if (event_list == NULL) {
190 return NGX_ERROR;
191 }
192 }
193
194 ngx_event_flags = NGX_USE_EVENTPORT_EVENT;
195
196 if (timer) {
197 ngx_memzero(&pn, sizeof(port_notify_t));
198 pn.portnfy_port = ep;
199
200 ngx_memzero(&sev, sizeof(struct sigevent));
201 sev.sigev_notify = SIGEV_PORT;
202 #if !(NGX_TEST_BUILD_EVENTPORT)
203 sev.sigev_value.sival_ptr = &pn;
204 #endif
205
206 if (timer_create(CLOCK_REALTIME, &sev, &event_timer) == -1) {
207 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
208 "timer_create() failed");
209 return NGX_ERROR;
210 }
211
212 its.it_interval.tv_sec = timer / 1000;
213 its.it_interval.tv_nsec = (timer % 1000) * 1000000;
214 its.it_value.tv_sec = timer / 1000;
215 its.it_value.tv_nsec = (timer % 1000) * 1000000;
216
217 if (timer_settime(event_timer, 0, &its, NULL) == -1) {
218 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
219 "timer_settime() failed");
220 return NGX_ERROR;
221 }
222
223 ngx_event_flags |= NGX_USE_TIMER_EVENT;
224 }
225
226 nevents = epcf->events;
227
228 ngx_io = ngx_os_io;
229
230 ngx_event_actions = ngx_eventport_module_ctx.actions;
231
232 return NGX_OK;
233 }
234
235
236 static void
237 ngx_eventport_done(ngx_cycle_t *cycle)
238 {
239 if (event_timer != -1) {
240 if (timer_delete(event_timer) == -1) {
241 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
242 "timer_delete() failed");
243 }
244
245 event_timer = -1;
246 }
247
248 if (close(ep) == -1) {
249 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
250 "close() event port failed");
251 }
252
253 ep = -1;
254
255 ngx_free(event_list);
256
257 event_list = NULL;
258 nevents = 0;
259 }
260
261
262 static ngx_int_t
263 ngx_eventport_add_event(ngx_event_t *ev, int event, u_int flags)
264 {
265 int events, prev;
266 ngx_event_t *e;
267 ngx_connection_t *c;
268
269 c = ev->data;
270
271 events = event;
272
273 if (event == NGX_READ_EVENT) {
274 e = c->write;
275 prev = POLLOUT;
276 #if (NGX_READ_EVENT != POLLIN)
277 events = POLLIN;
278 #endif
279
280 } else {
281 e = c->read;
282 prev = POLLIN;
283 #if (NGX_WRITE_EVENT != POLLOUT)
284 events = POLLOUT;
285 #endif
286 }
287
288 if (e->oneshot) {
289 events |= prev;
290 }
291
292 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
293 "eventport add event: fd:%d ev:%04Xd", c->fd, events);
294
295 if (port_associate(ep, PORT_SOURCE_FD, c->fd, events,
296 (void *) ((uintptr_t) ev | ev->instance))
297 == -1)
298 {
299 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
300 "port_associate() failed");
301 return NGX_ERROR;
302 }
303
304 ev->active = 1;
305 ev->oneshot = 1;
306
307 return NGX_OK;
308 }
309
310
311 static ngx_int_t
312 ngx_eventport_del_event(ngx_event_t *ev, int event, u_int flags)
313 {
314 ngx_event_t *e;
315 ngx_connection_t *c;
316
317 /*
318 * when the file descriptor is closed, the event port automatically
319 * dissociates it from the port, so we do not need to dissociate explicity
320 * the event before the closing the file descriptor
321 */
322
323 if (flags & NGX_CLOSE_EVENT) {
324 ev->active = 0;
325 ev->oneshot = 0;
326 return NGX_OK;
327 }
328
329 c = ev->data;
330
331 if (event == NGX_READ_EVENT) {
332 e = c->write;
333 event = POLLOUT;
334
335 } else {
336 e = c->read;
337 event = POLLIN;
338 }
339
340 if (e->oneshot) {
341 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
342 "eventport change event: fd:%d ev:%04Xd", c->fd, event);
343
344 if (port_associate(ep, PORT_SOURCE_FD, c->fd, event,
345 (void *) ((uintptr_t) ev | ev->instance))
346 == -1)
347 {
348 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
349 "port_associate() failed");
350 return NGX_ERROR;
351 }
352
353 } else {
354 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
355 "eventport del event: fd:%d", c->fd);
356
357 if (port_dissociate(ep, PORT_SOURCE_FD, c->fd) == -1) {
358 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
359 "port_dissociate() failed");
360 return NGX_ERROR;
361 }
362 }
363
364 ev->active = 0;
365 ev->oneshot = 0;
366
367 return NGX_OK;
368 }
369
370
371 ngx_int_t
372 ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
373 ngx_uint_t flags)
374 {
375 int n, revents;
376 u_int events;
377 ngx_err_t err;
378 ngx_int_t instance;
379 ngx_uint_t i, level;
380 ngx_event_t *ev, *rev, *wev, **queue;
381 ngx_connection_t *c;
382 struct timespec ts, *tp;
383
384 if (timer == NGX_TIMER_INFINITE) {
385 tp = NULL;
386
387 } else {
388 ts.tv_sec = timer / 1000;
389 ts.tv_nsec = (timer % 1000) * 1000000;
390 tp = &ts;
391 }
392
393 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
394 "eventport timer: %M", timer);
395
396 events = 1;
397
398 n = port_getn(ep, event_list, nevents, &events, tp);
399
400 err = ngx_errno;
401
402 if (flags & NGX_UPDATE_TIME) {
403 ngx_time_update(0, 0);
404 }
405
406 if (n == -1) {
407 if (err == ETIME) {
408 if (timer != NGX_TIMER_INFINITE) {
409 return NGX_OK;
410 }
411
412 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
413 "port_getn() returned no events without timeout");
414 return NGX_ERROR;
415 }
416
417 level = (err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT;
418 ngx_log_error(level, cycle->log, err, "port_getn() failed");
419 return NGX_ERROR;
420 }
421
422 if (events == 0) {
423 if (timer != NGX_TIMER_INFINITE) {
424 return NGX_OK;
425 }
426
427 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
428 "port_getn() returned no events without timeout");
429 return NGX_ERROR;
430 }
431
432 ngx_mutex_lock(ngx_posted_events_mutex);
433
434 for (i = 0; i < events; i++) {
435
436 if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
437 ngx_time_update(0, 0);
438 continue;
439 }
440
441 ev = event_list[i].portev_user;
442
443 switch (event_list[i].portev_source) {
444
445 case PORT_SOURCE_FD:
446
447 instance = (uintptr_t) ev & 1;
448 ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
449
450 if (ev->closed || ev->instance != instance) {
451
452 /*
453 * the stale event from a file descriptor
454 * that was just closed in this iteration
455 */
456
457 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
458 "eventport: stale event %p", ev);
459 continue;
460 }
461
462 revents = event_list[i].portev_events;
463
464 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
465 "eventport: fd:%d, ev:%04Xd",
466 event_list[i].portev_object, revents);
467
468 if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
469 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
470 "prot_getn() error fd:%d ev:%04Xd",
471 event_list[i].portev_object, revents);
472 }
473
474 if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
475 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
476 "strange port_getn() events fd:%d ev:%04Xd",
477 event_list[i].portev_object, revents);
478 }
479
480 if ((revents & (POLLERR|POLLHUP|POLLNVAL))
481 && (revents & (POLLIN|POLLOUT)) == 0)
482 {
483 /*
484 * if the error events were returned without POLLIN or POLLOUT,
485 * then add these flags to handle the events at least in one
486 * active handler
487 */
488
489 revents |= POLLIN|POLLOUT;
490 }
491
492 c = ev->data;
493 rev = c->read;
494 wev = c->write;
495
496 rev->active = 0;
497 wev->active = 0;
498
499 if (revents & POLLIN) {
500
501 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
502 rev->posted_ready = 1;
503
504 } else {
505 rev->ready = 1;
506 }
507
508 if (flags & NGX_POST_EVENTS) {
509 queue = (ngx_event_t **) (rev->accept ?
510 &ngx_posted_accept_events : &ngx_posted_events);
511
512 ngx_locked_post_event(rev, queue);
513
514 } else {
515 rev->handler(rev);
516 }
517
518 if (rev->accept) {
519 if (ngx_use_accept_mutex) {
520 ngx_accept_events = 1;
521 continue;
522 }
523
524 if (port_associate(ep, PORT_SOURCE_FD, c->fd, POLLIN,
525 (void *) ((uintptr_t) ev | ev->instance))
526 == -1)
527 {
528 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
529 "port_associate() failed");
530 return NGX_ERROR;
531 }
532 }
533 }
534
535 if (revents & POLLOUT) {
536
537 if (flags & NGX_POST_THREAD_EVENTS) {
538 wev->posted_ready = 1;
539
540 } else {
541 wev->ready = 1;
542 }
543
544 if (flags & NGX_POST_EVENTS) {
545 ngx_locked_post_event(wev, &ngx_posted_events);
546
547 } else {
548 wev->handler(wev);
549 }
550 }
551
552 continue;
553
554 default:
555 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
556 "unexpected even_port object %d",
557 event_list[i].portev_object);
558 continue;
559 }
560 }
561
562 ngx_mutex_unlock(ngx_posted_events_mutex);
563
564 return NGX_OK;
565 }
566
567
568 static void *
569 ngx_eventport_create_conf(ngx_cycle_t *cycle)
570 {
571 ngx_eventport_conf_t *epcf;
572
573 epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t));
574 if (epcf == NULL) {
575 return NGX_CONF_ERROR;
576 }
577
578 epcf->events = NGX_CONF_UNSET;
579
580 return epcf;
581 }
582
583
584 static char *
585 ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf)
586 {
587 ngx_eventport_conf_t *epcf = conf;
588
589 ngx_conf_init_uint_value(epcf->events, 32);
590
591 return NGX_CONF_OK;
592 }
1212
1313
1414 extern ngx_module_t ngx_kqueue_module;
15 extern ngx_module_t ngx_eventport_module;
1516 extern ngx_module_t ngx_devpoll_module;
1617 extern ngx_module_t ngx_epoll_module;
1718 extern ngx_module_t ngx_rtsig_module;
4849 ngx_atomic_t *ngx_accept_mutex_ptr;
4950 ngx_shmtx_t ngx_accept_mutex;
5051 ngx_uint_t ngx_use_accept_mutex;
52 ngx_uint_t ngx_accept_events;
5153 ngx_uint_t ngx_accept_mutex_held;
5254 ngx_msec_t ngx_accept_mutex_delay;
5355 ngx_int_t ngx_accept_disabled;
313315 return NGX_OK;
314316 }
315317
316 } else if (ngx_event_flags & NGX_USE_ONESHOT_EVENT) {
318 } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
317319
318320 /* event ports */
319321
320 if (!rev->active) {
321 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_ONESHOT_EVENT)
322 == NGX_ERROR)
323 {
324 return NGX_ERROR;
325 }
326 }
327
328 return NGX_OK;
322 if (!rev->active && !rev->ready) {
323 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
324 return NGX_ERROR;
325 }
326
327 return NGX_OK;
328 }
329
330 if (rev->oneshot && !rev->ready) {
331 if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
332 return NGX_ERROR;
333 }
334
335 return NGX_OK;
336 }
329337 }
330338
331339 /* aio, iocp, rtsig */
340348 ngx_connection_t *c;
341349
342350 if (lowat) {
343 c = (ngx_connection_t *) wev->data;
351 c = wev->data;
344352
345353 if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
346354 return NGX_ERROR;
386394 return NGX_OK;
387395 }
388396
389 } else if (ngx_event_flags & NGX_USE_ONESHOT_EVENT) {
397 } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
390398
391399 /* event ports */
392400
393 if (!wev->active) {
394 if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT)
395 == NGX_ERROR)
396 {
397 return NGX_ERROR;
398 }
399 }
400
401 return NGX_OK;
401 if (!wev->active && !wev->ready) {
402 if (ngx_add_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
403 return NGX_ERROR;
404 }
405
406 return NGX_OK;
407 }
408
409 if (wev->oneshot && wev->ready) {
410 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
411 return NGX_ERROR;
412 }
413
414 return NGX_OK;
415 }
402416 }
403417
404418 /* aio, iocp, rtsig */
11971211 event_module = ngx_modules[i]->ctx;
11981212
11991213 if (ngx_strcmp(event_module->name->data, event_core_name.data)
1200 == 0)
1214 == 0)
12011215 {
12021216 continue;
12031217 }
4040
4141 unsigned accept:1;
4242
43 unsigned oneshot:1;
44
4543 /* used to detect the stale events in kqueue, rt signals and epoll */
4644 unsigned instance:1;
4745
5553
5654 /* the ready event; in aio mode 0 means that no operation can be posted */
5755 unsigned ready:1;
56
57 unsigned oneshot:1;
5858
5959 /* aio operation is complete */
6060 unsigned complete:1;
223223
224224 /*
225225 * The event filter is deleted after a notification without an additional
226 * syscall: kqueue, epoll, Solaris 10's event ports.
226 * syscall: kqueue, epoll.
227227 */
228228 #define NGX_USE_ONESHOT_EVENT 0x00000002
229229
285285 */
286286 #define NGX_USE_TIMER_EVENT 0x00000800
287287
288 /*
289 * All event filters on file descriptor are deleted after a notification:
290 * Solaris 10's event ports.
291 */
292 #define NGX_USE_EVENTPORT_EVENT 0x00001000
293
288294
289295
290296 /*
291297 * The event filter is deleted before the closing file.
292 * Has no meaning for select, poll, epoll.
293 *
294 * kqueue: kqueue deletes event filters for file that closed
295 * so we need only to delete filters in user-level batch array
298 * Has no meaning for select, poll, kqueue, epoll.
296299 * /dev/poll: we need to flush POLLREMOVE event before closing file
297300 */
298301
334337 #define NGX_DISABLE_EVENT EV_DISABLE
335338
336339
337 #elif (NGX_HAVE_DEVPOLL)
340 #elif (NGX_HAVE_DEVPOLL || NGX_HAVE_EVENTPORT)
338341
339342 #define NGX_READ_EVENT POLLIN
340343 #define NGX_WRITE_EVENT POLLOUT
445448 extern ngx_atomic_t *ngx_accept_mutex_ptr;
446449 extern ngx_shmtx_t ngx_accept_mutex;
447450 extern ngx_uint_t ngx_use_accept_mutex;
451 extern ngx_uint_t ngx_accept_events;
448452 extern ngx_uint_t ngx_accept_mutex_held;
449453 extern ngx_msec_t ngx_accept_mutex_delay;
450454 extern ngx_int_t ngx_accept_disabled;
5555 err = ngx_socket_errno;
5656
5757 if (err == NGX_EAGAIN) {
58 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
59 "accept() not ready");
5860 return;
5961 }
6062
263265 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
264266 "accept mutex locked");
265267
266 if (ngx_accept_mutex_held && !(ngx_event_flags & NGX_USE_RTSIG_EVENT)) {
268 if (ngx_accept_mutex_held
269 && ngx_accept_events == 0
270 && !(ngx_event_flags & NGX_USE_RTSIG_EVENT))
271 {
267272 return NGX_OK;
268273 }
269274
272277 return NGX_ERROR;
273278 }
274279
280 ngx_accept_events = 0;
275281 ngx_accept_mutex_held = 1;
276282
277283 return NGX_OK;
278284 }
285
286 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
287 "accept mutex lock failed: %ui", ngx_accept_mutex_held);
279288
280289 if (ngx_accept_mutex_held) {
281290 if (ngx_disable_accept_events(cycle) == NGX_ERROR) {
7373 #endif
7474
7575
76 #if (NGX_HAVE_EVENTPORT)
77 #include <port.h>
78 #endif
79
80
7681 #ifndef NGX_HAVE_INHERITED_NONBLOCK
7782 #define NGX_HAVE_INHERITED_NONBLOCK 1
7883 #endif