Mercurial > hg > nginx-quic
annotate src/event/modules/ngx_eventport_module.c @ 4515:8bb695c05870 stable-1.0
Merge of r4498:
Fix of rbtree lookup on hash collisions.
Previous code incorrectly assumed that nodes with identical keys are linked
together. This might not be true after tree rebalance.
Patch by Lanshun Zhou.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 05 Mar 2012 13:17:56 +0000 |
parents | 4919fb357a5d |
children | 67653855682e |
rev | line source |
---|---|
719 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4450
4919fb357a5d
Merge of r4406, r4413: copyrights updated.
Maxim Dounin <mdounin@mdounin.ru>
parents:
3475
diff
changeset
|
4 * Copyright (C) Nginx, Inc. |
719 | 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_EVENTPORT) | |
14 | |
15 #define ushort_t u_short | |
16 #define uint_t u_int | |
17 | |
18 /* Solaris declarations */ | |
19 | |
20 #define PORT_SOURCE_AIO 1 | |
21 #define PORT_SOURCE_TIMER 2 | |
22 #define PORT_SOURCE_USER 3 | |
23 #define PORT_SOURCE_FD 4 | |
24 #define PORT_SOURCE_ALERT 5 | |
25 #define PORT_SOURCE_MQ 6 | |
26 | |
27 #define ETIME 64 | |
28 | |
29 #define SIGEV_PORT 4 | |
30 | |
31 typedef struct { | |
32 int portev_events; /* event data is source specific */ | |
33 ushort_t portev_source; /* event source */ | |
34 ushort_t portev_pad; /* port internal use */ | |
35 uintptr_t portev_object; /* source specific object */ | |
36 void *portev_user; /* user cookie */ | |
37 } port_event_t; | |
38 | |
39 typedef struct port_notify { | |
40 int portnfy_port; /* bind request(s) to port */ | |
41 void *portnfy_user; /* user defined */ | |
42 } port_notify_t; | |
43 | |
1939
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
44 #if (__FreeBSD_version < 700005) |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
45 |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
46 typedef struct itimerspec { /* definition per POSIX.4 */ |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
47 struct timespec it_interval;/* timer period */ |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
48 struct timespec it_value; /* timer expiration */ |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
49 } itimerspec_t; |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
50 |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
51 #endif |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
52 |
719 | 53 int port_create(void) |
54 { | |
55 return -1; | |
56 } | |
57 | |
58 int port_associate(int port, int source, uintptr_t object, int events, | |
59 void *user) | |
60 { | |
61 return -1; | |
62 } | |
63 | |
64 int port_dissociate(int port, int source, uintptr_t object) | |
65 { | |
66 return -1; | |
67 } | |
68 | |
69 int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget, | |
70 struct timespec *timeout) | |
71 { | |
72 return -1; | |
73 } | |
74 | |
75 int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid) | |
76 { | |
77 return -1; | |
78 } | |
79 | |
80 int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, | |
81 struct itimerspec *ovalue) | |
82 { | |
83 return -1; | |
84 } | |
85 | |
86 int timer_delete(timer_t timerid) | |
87 { | |
88 return -1; | |
89 } | |
90 | |
91 #endif | |
92 | |
93 | |
94 typedef struct { | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
95 ngx_uint_t events; |
719 | 96 } ngx_eventport_conf_t; |
97 | |
98 | |
99 static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer); | |
100 static void ngx_eventport_done(ngx_cycle_t *cycle); | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
101 static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, |
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
102 ngx_uint_t flags); |
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
103 static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, |
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
104 ngx_uint_t flags); |
719 | 105 static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle, |
106 ngx_msec_t timer, ngx_uint_t flags); | |
107 | |
108 static void *ngx_eventport_create_conf(ngx_cycle_t *cycle); | |
109 static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf); | |
110 | |
111 static int ep = -1; | |
112 static port_event_t *event_list; | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
113 static ngx_uint_t nevents; |
1870
a62fb6c156c5
fix building --test-build-rtsig and --test-build-eventport on FreeBSD 7
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
114 static timer_t event_timer = (timer_t) -1; |
719 | 115 |
116 static ngx_str_t eventport_name = ngx_string("eventport"); | |
117 | |
118 | |
119 static ngx_command_t ngx_eventport_commands[] = { | |
120 | |
121 { ngx_string("eventport_events"), | |
122 NGX_EVENT_CONF|NGX_CONF_TAKE1, | |
123 ngx_conf_set_num_slot, | |
124 0, | |
125 offsetof(ngx_eventport_conf_t, events), | |
126 NULL }, | |
127 | |
128 ngx_null_command | |
129 }; | |
130 | |
131 | |
132 ngx_event_module_t ngx_eventport_module_ctx = { | |
133 &eventport_name, | |
134 ngx_eventport_create_conf, /* create configuration */ | |
135 ngx_eventport_init_conf, /* init configuration */ | |
136 | |
137 { | |
138 ngx_eventport_add_event, /* add an event */ | |
139 ngx_eventport_del_event, /* delete an event */ | |
140 ngx_eventport_add_event, /* enable an event */ | |
141 ngx_eventport_del_event, /* disable an event */ | |
142 NULL, /* add an connection */ | |
143 NULL, /* delete an connection */ | |
144 NULL, /* process the changes */ | |
145 ngx_eventport_process_events, /* process the events */ | |
146 ngx_eventport_init, /* init the events */ | |
147 ngx_eventport_done, /* done the events */ | |
148 } | |
149 | |
150 }; | |
151 | |
152 ngx_module_t ngx_eventport_module = { | |
153 NGX_MODULE_V1, | |
154 &ngx_eventport_module_ctx, /* module context */ | |
155 ngx_eventport_commands, /* module directives */ | |
156 NGX_EVENT_MODULE, /* module type */ | |
157 NULL, /* init master */ | |
158 NULL, /* init module */ | |
159 NULL, /* init process */ | |
160 NULL, /* init thread */ | |
161 NULL, /* exit thread */ | |
162 NULL, /* exit process */ | |
163 NULL, /* exit master */ | |
164 NGX_MODULE_V1_PADDING | |
165 }; | |
166 | |
167 | |
168 static ngx_int_t | |
169 ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer) | |
170 { | |
171 port_notify_t pn; | |
172 struct itimerspec its; | |
173 struct sigevent sev; | |
174 ngx_eventport_conf_t *epcf; | |
175 | |
176 epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_eventport_module); | |
177 | |
178 if (ep == -1) { | |
179 ep = port_create(); | |
180 | |
181 if (ep == -1) { | |
182 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
183 "port_create() failed"); | |
184 return NGX_ERROR; | |
185 } | |
186 } | |
187 | |
188 if (nevents < epcf->events) { | |
189 if (event_list) { | |
190 ngx_free(event_list); | |
191 } | |
192 | |
193 event_list = ngx_alloc(sizeof(port_event_t) * epcf->events, | |
194 cycle->log); | |
195 if (event_list == NULL) { | |
196 return NGX_ERROR; | |
197 } | |
198 } | |
199 | |
200 ngx_event_flags = NGX_USE_EVENTPORT_EVENT; | |
201 | |
202 if (timer) { | |
203 ngx_memzero(&pn, sizeof(port_notify_t)); | |
204 pn.portnfy_port = ep; | |
205 | |
206 ngx_memzero(&sev, sizeof(struct sigevent)); | |
207 sev.sigev_notify = SIGEV_PORT; | |
208 #if !(NGX_TEST_BUILD_EVENTPORT) | |
209 sev.sigev_value.sival_ptr = &pn; | |
210 #endif | |
211 | |
212 if (timer_create(CLOCK_REALTIME, &sev, &event_timer) == -1) { | |
213 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
214 "timer_create() failed"); | |
215 return NGX_ERROR; | |
216 } | |
217 | |
218 its.it_interval.tv_sec = timer / 1000; | |
219 its.it_interval.tv_nsec = (timer % 1000) * 1000000; | |
220 its.it_value.tv_sec = timer / 1000; | |
221 its.it_value.tv_nsec = (timer % 1000) * 1000000; | |
222 | |
223 if (timer_settime(event_timer, 0, &its, NULL) == -1) { | |
224 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
225 "timer_settime() failed"); | |
226 return NGX_ERROR; | |
227 } | |
228 | |
229 ngx_event_flags |= NGX_USE_TIMER_EVENT; | |
230 } | |
231 | |
232 nevents = epcf->events; | |
233 | |
234 ngx_io = ngx_os_io; | |
235 | |
236 ngx_event_actions = ngx_eventport_module_ctx.actions; | |
237 | |
238 return NGX_OK; | |
239 } | |
240 | |
241 | |
242 static void | |
243 ngx_eventport_done(ngx_cycle_t *cycle) | |
244 { | |
1870
a62fb6c156c5
fix building --test-build-rtsig and --test-build-eventport on FreeBSD 7
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
245 if (event_timer != (timer_t) -1) { |
719 | 246 if (timer_delete(event_timer) == -1) { |
247 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
248 "timer_delete() failed"); | |
249 } | |
250 | |
1870
a62fb6c156c5
fix building --test-build-rtsig and --test-build-eventport on FreeBSD 7
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
251 event_timer = (timer_t) -1; |
719 | 252 } |
253 | |
254 if (close(ep) == -1) { | |
255 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
256 "close() event port failed"); | |
257 } | |
258 | |
259 ep = -1; | |
260 | |
261 ngx_free(event_list); | |
262 | |
263 event_list = NULL; | |
264 nevents = 0; | |
265 } | |
266 | |
267 | |
268 static ngx_int_t | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
269 ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) |
719 | 270 { |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
271 ngx_int_t events, prev; |
719 | 272 ngx_event_t *e; |
273 ngx_connection_t *c; | |
274 | |
275 c = ev->data; | |
276 | |
277 events = event; | |
278 | |
279 if (event == NGX_READ_EVENT) { | |
280 e = c->write; | |
281 prev = POLLOUT; | |
282 #if (NGX_READ_EVENT != POLLIN) | |
283 events = POLLIN; | |
284 #endif | |
285 | |
286 } else { | |
287 e = c->read; | |
288 prev = POLLIN; | |
289 #if (NGX_WRITE_EVENT != POLLOUT) | |
290 events = POLLOUT; | |
291 #endif | |
292 } | |
293 | |
294 if (e->oneshot) { | |
295 events |= prev; | |
296 } | |
297 | |
298 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
299 "eventport add event: fd:%d ev:%04Xi", c->fd, events); |
719 | 300 |
301 if (port_associate(ep, PORT_SOURCE_FD, c->fd, events, | |
302 (void *) ((uintptr_t) ev | ev->instance)) | |
303 == -1) | |
304 { | |
305 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
306 "port_associate() failed"); | |
307 return NGX_ERROR; | |
308 } | |
309 | |
310 ev->active = 1; | |
311 ev->oneshot = 1; | |
312 | |
313 return NGX_OK; | |
314 } | |
315 | |
316 | |
317 static ngx_int_t | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
318 ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) |
719 | 319 { |
320 ngx_event_t *e; | |
321 ngx_connection_t *c; | |
322 | |
323 /* | |
324 * when the file descriptor is closed, the event port automatically | |
325 * dissociates it from the port, so we do not need to dissociate explicity | |
326 * the event before the closing the file descriptor | |
327 */ | |
328 | |
329 if (flags & NGX_CLOSE_EVENT) { | |
330 ev->active = 0; | |
331 ev->oneshot = 0; | |
332 return NGX_OK; | |
333 } | |
334 | |
335 c = ev->data; | |
336 | |
337 if (event == NGX_READ_EVENT) { | |
338 e = c->write; | |
339 event = POLLOUT; | |
340 | |
341 } else { | |
342 e = c->read; | |
343 event = POLLIN; | |
344 } | |
345 | |
346 if (e->oneshot) { | |
347 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
348 "eventport change event: fd:%d ev:%04Xi", c->fd, event); |
719 | 349 |
350 if (port_associate(ep, PORT_SOURCE_FD, c->fd, event, | |
351 (void *) ((uintptr_t) ev | ev->instance)) | |
352 == -1) | |
353 { | |
354 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
355 "port_associate() failed"); | |
356 return NGX_ERROR; | |
357 } | |
358 | |
359 } else { | |
360 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
361 "eventport del event: fd:%d", c->fd); | |
362 | |
363 if (port_dissociate(ep, PORT_SOURCE_FD, c->fd) == -1) { | |
364 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
365 "port_dissociate() failed"); | |
366 return NGX_ERROR; | |
367 } | |
368 } | |
369 | |
370 ev->active = 0; | |
371 ev->oneshot = 0; | |
372 | |
373 return NGX_OK; | |
374 } | |
375 | |
376 | |
377 ngx_int_t | |
378 ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, | |
379 ngx_uint_t flags) | |
380 { | |
381 int n, revents; | |
382 u_int events; | |
383 ngx_err_t err; | |
384 ngx_int_t instance; | |
385 ngx_uint_t i, level; | |
386 ngx_event_t *ev, *rev, *wev, **queue; | |
387 ngx_connection_t *c; | |
388 struct timespec ts, *tp; | |
389 | |
390 if (timer == NGX_TIMER_INFINITE) { | |
391 tp = NULL; | |
392 | |
393 } else { | |
394 ts.tv_sec = timer / 1000; | |
395 ts.tv_nsec = (timer % 1000) * 1000000; | |
396 tp = &ts; | |
397 } | |
398 | |
399 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
400 "eventport timer: %M", timer); | |
401 | |
402 events = 1; | |
403 | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
404 n = port_getn(ep, event_list, (u_int) nevents, &events, tp); |
719 | 405 |
406 err = ngx_errno; | |
407 | |
408 if (flags & NGX_UPDATE_TIME) { | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
409 ngx_time_update(); |
719 | 410 } |
411 | |
412 if (n == -1) { | |
413 if (err == ETIME) { | |
414 if (timer != NGX_TIMER_INFINITE) { | |
415 return NGX_OK; | |
416 } | |
417 | |
418 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
419 "port_getn() returned no events without timeout"); | |
420 return NGX_ERROR; | |
421 } | |
422 | |
423 level = (err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT; | |
424 ngx_log_error(level, cycle->log, err, "port_getn() failed"); | |
425 return NGX_ERROR; | |
426 } | |
427 | |
428 if (events == 0) { | |
429 if (timer != NGX_TIMER_INFINITE) { | |
430 return NGX_OK; | |
431 } | |
432 | |
433 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
434 "port_getn() returned no events without timeout"); | |
435 return NGX_ERROR; | |
436 } | |
437 | |
438 ngx_mutex_lock(ngx_posted_events_mutex); | |
439 | |
440 for (i = 0; i < events; i++) { | |
441 | |
442 if (event_list[i].portev_source == PORT_SOURCE_TIMER) { | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
443 ngx_time_update(); |
719 | 444 continue; |
445 } | |
446 | |
447 ev = event_list[i].portev_user; | |
448 | |
449 switch (event_list[i].portev_source) { | |
450 | |
451 case PORT_SOURCE_FD: | |
452 | |
453 instance = (uintptr_t) ev & 1; | |
454 ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1); | |
455 | |
456 if (ev->closed || ev->instance != instance) { | |
457 | |
458 /* | |
459 * the stale event from a file descriptor | |
460 * that was just closed in this iteration | |
461 */ | |
462 | |
463 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
464 "eventport: stale event %p", ev); | |
465 continue; | |
466 } | |
467 | |
468 revents = event_list[i].portev_events; | |
469 | |
470 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
471 "eventport: fd:%d, ev:%04Xd", | |
472 event_list[i].portev_object, revents); | |
473 | |
474 if (revents & (POLLERR|POLLHUP|POLLNVAL)) { | |
1128
06479b01caff
decrease log level from alert to debug for POLLERR|POLLHUP|POLLNVAL
Igor Sysoev <igor@sysoev.ru>
parents:
929
diff
changeset
|
475 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
06479b01caff
decrease log level from alert to debug for POLLERR|POLLHUP|POLLNVAL
Igor Sysoev <igor@sysoev.ru>
parents:
929
diff
changeset
|
476 "port_getn() error fd:%d ev:%04Xd", |
06479b01caff
decrease log level from alert to debug for POLLERR|POLLHUP|POLLNVAL
Igor Sysoev <igor@sysoev.ru>
parents:
929
diff
changeset
|
477 event_list[i].portev_object, revents); |
719 | 478 } |
479 | |
480 if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { | |
481 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
482 "strange port_getn() events fd:%d ev:%04Xd", | |
483 event_list[i].portev_object, revents); | |
484 } | |
485 | |
486 if ((revents & (POLLERR|POLLHUP|POLLNVAL)) | |
487 && (revents & (POLLIN|POLLOUT)) == 0) | |
488 { | |
489 /* | |
490 * if the error events were returned without POLLIN or POLLOUT, | |
491 * then add these flags to handle the events at least in one | |
492 * active handler | |
493 */ | |
494 | |
495 revents |= POLLIN|POLLOUT; | |
496 } | |
497 | |
498 c = ev->data; | |
499 rev = c->read; | |
500 wev = c->write; | |
501 | |
502 rev->active = 0; | |
503 wev->active = 0; | |
504 | |
505 if (revents & POLLIN) { | |
754
4ac89c5aa10d
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
719
diff
changeset
|
506 |
719 | 507 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) { |
508 rev->posted_ready = 1; | |
509 | |
510 } else { | |
511 rev->ready = 1; | |
512 } | |
513 | |
514 if (flags & NGX_POST_EVENTS) { | |
515 queue = (ngx_event_t **) (rev->accept ? | |
516 &ngx_posted_accept_events : &ngx_posted_events); | |
517 | |
518 ngx_locked_post_event(rev, queue); | |
519 | |
520 } else { | |
521 rev->handler(rev); | |
1287
3dd9883fa121
fix segfault when event port returns POLLERR without POLLIN or POLLOUT
Igor Sysoev <igor@sysoev.ru>
parents:
1128
diff
changeset
|
522 |
3dd9883fa121
fix segfault when event port returns POLLERR without POLLIN or POLLOUT
Igor Sysoev <igor@sysoev.ru>
parents:
1128
diff
changeset
|
523 if (ev->closed) { |
3dd9883fa121
fix segfault when event port returns POLLERR without POLLIN or POLLOUT
Igor Sysoev <igor@sysoev.ru>
parents:
1128
diff
changeset
|
524 continue; |
3dd9883fa121
fix segfault when event port returns POLLERR without POLLIN or POLLOUT
Igor Sysoev <igor@sysoev.ru>
parents:
1128
diff
changeset
|
525 } |
719 | 526 } |
527 | |
528 if (rev->accept) { | |
529 if (ngx_use_accept_mutex) { | |
530 ngx_accept_events = 1; | |
531 continue; | |
532 } | |
533 | |
534 if (port_associate(ep, PORT_SOURCE_FD, c->fd, POLLIN, | |
535 (void *) ((uintptr_t) ev | ev->instance)) | |
536 == -1) | |
537 { | |
538 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
539 "port_associate() failed"); | |
540 return NGX_ERROR; | |
541 } | |
542 } | |
543 } | |
544 | |
545 if (revents & POLLOUT) { | |
546 | |
547 if (flags & NGX_POST_THREAD_EVENTS) { | |
548 wev->posted_ready = 1; | |
549 | |
550 } else { | |
551 wev->ready = 1; | |
552 } | |
553 | |
554 if (flags & NGX_POST_EVENTS) { | |
555 ngx_locked_post_event(wev, &ngx_posted_events); | |
556 | |
557 } else { | |
558 wev->handler(wev); | |
559 } | |
560 } | |
561 | |
562 continue; | |
563 | |
564 default: | |
565 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
566 "unexpected even_port object %d", | |
567 event_list[i].portev_object); | |
568 continue; | |
569 } | |
570 } | |
571 | |
572 ngx_mutex_unlock(ngx_posted_events_mutex); | |
573 | |
574 return NGX_OK; | |
575 } | |
576 | |
577 | |
578 static void * | |
579 ngx_eventport_create_conf(ngx_cycle_t *cycle) | |
580 { | |
581 ngx_eventport_conf_t *epcf; | |
582 | |
583 epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t)); | |
584 if (epcf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
1939
diff
changeset
|
585 return NULL; |
719 | 586 } |
587 | |
588 epcf->events = NGX_CONF_UNSET; | |
589 | |
590 return epcf; | |
591 } | |
592 | |
593 | |
594 static char * | |
595 ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf) | |
596 { | |
597 ngx_eventport_conf_t *epcf = conf; | |
598 | |
599 ngx_conf_init_uint_value(epcf->events, 32); | |
600 | |
601 return NGX_CONF_OK; | |
602 } |