Mercurial > hg > nginx-quic
annotate src/event/modules/ngx_eventport_module.c @ 7107:d4b031cf32cf
HTTP/2: fixed debug log about indexed headers.
Previously, "get indexed header" message was logged when in fact only
header name was obtained using an index, and "get indexed header name"
was logged when full header representation (name and value) was obtained
using an index. Fixed version logs "get indexed name" and "get indexed
header" respectively.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 14 Sep 2017 19:06:05 +0300 |
parents | fbdaad9b0e7b |
children | cbf59d483c9c |
rev | line source |
---|---|
719 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 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 | |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
18 #ifndef CLOCK_REALTIME |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
19 #define CLOCK_REALTIME 0 |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
20 typedef int clockid_t; |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
21 typedef void * timer_t; |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
22 #endif |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
23 |
719 | 24 /* Solaris declarations */ |
25 | |
26 #define PORT_SOURCE_AIO 1 | |
27 #define PORT_SOURCE_TIMER 2 | |
28 #define PORT_SOURCE_USER 3 | |
29 #define PORT_SOURCE_FD 4 | |
30 #define PORT_SOURCE_ALERT 5 | |
31 #define PORT_SOURCE_MQ 6 | |
32 | |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
33 #ifndef ETIME |
719 | 34 #define ETIME 64 |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
35 #endif |
719 | 36 |
37 #define SIGEV_PORT 4 | |
38 | |
39 typedef struct { | |
40 int portev_events; /* event data is source specific */ | |
41 ushort_t portev_source; /* event source */ | |
42 ushort_t portev_pad; /* port internal use */ | |
43 uintptr_t portev_object; /* source specific object */ | |
44 void *portev_user; /* user cookie */ | |
45 } port_event_t; | |
46 | |
47 typedef struct port_notify { | |
48 int portnfy_port; /* bind request(s) to port */ | |
49 void *portnfy_user; /* user defined */ | |
50 } port_notify_t; | |
51 | |
6475
7d6970ba5209
Events: fixed test building with eventport on OS X.
Ruslan Ermilov <ru@nginx.com>
parents:
6447
diff
changeset
|
52 #if (__FreeBSD__ && __FreeBSD_version < 700005) || (NGX_DARWIN) |
1939
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
53 |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
54 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
|
55 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
|
56 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
|
57 } itimerspec_t; |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
58 |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
59 #endif |
6e7daf852eec
restore building --test-build-rtsig and --test-build-eventport on FreeBSD 6
Igor Sysoev <igor@sysoev.ru>
parents:
1870
diff
changeset
|
60 |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
61 int port_create(void); |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
62 |
719 | 63 int port_create(void) |
64 { | |
65 return -1; | |
66 } | |
67 | |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
68 |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
69 int port_associate(int port, int source, uintptr_t object, int events, |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
70 void *user); |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
71 |
719 | 72 int port_associate(int port, int source, uintptr_t object, int events, |
73 void *user) | |
74 { | |
75 return -1; | |
76 } | |
77 | |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
78 |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
79 int port_dissociate(int port, int source, uintptr_t object); |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
80 |
719 | 81 int port_dissociate(int port, int source, uintptr_t object) |
82 { | |
83 return -1; | |
84 } | |
85 | |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
86 |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
87 int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget, |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
88 struct timespec *timeout); |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
89 |
719 | 90 int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget, |
91 struct timespec *timeout) | |
92 { | |
93 return -1; | |
94 } | |
95 | |
6021
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
96 int port_send(int port, int events, void *user); |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
97 |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
98 int port_send(int port, int events, void *user) |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
99 { |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
100 return -1; |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
101 } |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
102 |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
103 |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
104 int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid); |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
105 |
719 | 106 int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid) |
107 { | |
108 return -1; | |
109 } | |
110 | |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
111 |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
112 int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
113 struct itimerspec *ovalue); |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
114 |
719 | 115 int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, |
116 struct itimerspec *ovalue) | |
117 { | |
118 return -1; | |
119 } | |
120 | |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
121 |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
122 int timer_delete(timer_t timerid); |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4572
diff
changeset
|
123 |
719 | 124 int timer_delete(timer_t timerid) |
125 { | |
126 return -1; | |
127 } | |
128 | |
129 #endif | |
130 | |
131 | |
132 typedef struct { | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
133 ngx_uint_t events; |
719 | 134 } ngx_eventport_conf_t; |
135 | |
136 | |
137 static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer); | |
138 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
|
139 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
|
140 ngx_uint_t flags); |
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
141 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
|
142 ngx_uint_t flags); |
6021
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
143 static ngx_int_t ngx_eventport_notify(ngx_event_handler_pt handler); |
719 | 144 static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle, |
145 ngx_msec_t timer, ngx_uint_t flags); | |
146 | |
147 static void *ngx_eventport_create_conf(ngx_cycle_t *cycle); | |
148 static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf); | |
149 | |
150 static int ep = -1; | |
151 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
|
152 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
|
153 static timer_t event_timer = (timer_t) -1; |
6021
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
154 static ngx_event_t notify_event; |
719 | 155 |
156 static ngx_str_t eventport_name = ngx_string("eventport"); | |
157 | |
158 | |
159 static ngx_command_t ngx_eventport_commands[] = { | |
160 | |
161 { ngx_string("eventport_events"), | |
162 NGX_EVENT_CONF|NGX_CONF_TAKE1, | |
163 ngx_conf_set_num_slot, | |
164 0, | |
165 offsetof(ngx_eventport_conf_t, events), | |
166 NULL }, | |
167 | |
168 ngx_null_command | |
169 }; | |
170 | |
171 | |
6922
a72886067bbb
Added missing static specifiers.
Eran Kornblau <erankor@gmail.com>
parents:
6806
diff
changeset
|
172 static ngx_event_module_t ngx_eventport_module_ctx = { |
719 | 173 &eventport_name, |
174 ngx_eventport_create_conf, /* create configuration */ | |
175 ngx_eventport_init_conf, /* init configuration */ | |
176 | |
177 { | |
178 ngx_eventport_add_event, /* add an event */ | |
179 ngx_eventport_del_event, /* delete an event */ | |
180 ngx_eventport_add_event, /* enable an event */ | |
181 ngx_eventport_del_event, /* disable an event */ | |
182 NULL, /* add an connection */ | |
183 NULL, /* delete an connection */ | |
6021
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
184 ngx_eventport_notify, /* trigger a notify */ |
719 | 185 ngx_eventport_process_events, /* process the events */ |
186 ngx_eventport_init, /* init the events */ | |
187 ngx_eventport_done, /* done the events */ | |
188 } | |
189 | |
190 }; | |
191 | |
192 ngx_module_t ngx_eventport_module = { | |
193 NGX_MODULE_V1, | |
194 &ngx_eventport_module_ctx, /* module context */ | |
195 ngx_eventport_commands, /* module directives */ | |
196 NGX_EVENT_MODULE, /* module type */ | |
197 NULL, /* init master */ | |
198 NULL, /* init module */ | |
199 NULL, /* init process */ | |
200 NULL, /* init thread */ | |
201 NULL, /* exit thread */ | |
202 NULL, /* exit process */ | |
203 NULL, /* exit master */ | |
204 NGX_MODULE_V1_PADDING | |
205 }; | |
206 | |
207 | |
208 static ngx_int_t | |
209 ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer) | |
210 { | |
211 port_notify_t pn; | |
212 struct itimerspec its; | |
213 struct sigevent sev; | |
214 ngx_eventport_conf_t *epcf; | |
215 | |
216 epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_eventport_module); | |
217 | |
218 if (ep == -1) { | |
219 ep = port_create(); | |
220 | |
221 if (ep == -1) { | |
222 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
223 "port_create() failed"); | |
224 return NGX_ERROR; | |
225 } | |
6021
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
226 |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
227 notify_event.active = 1; |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
228 notify_event.log = cycle->log; |
719 | 229 } |
230 | |
231 if (nevents < epcf->events) { | |
232 if (event_list) { | |
233 ngx_free(event_list); | |
234 } | |
235 | |
236 event_list = ngx_alloc(sizeof(port_event_t) * epcf->events, | |
237 cycle->log); | |
238 if (event_list == NULL) { | |
239 return NGX_ERROR; | |
240 } | |
241 } | |
242 | |
243 ngx_event_flags = NGX_USE_EVENTPORT_EVENT; | |
244 | |
245 if (timer) { | |
246 ngx_memzero(&pn, sizeof(port_notify_t)); | |
247 pn.portnfy_port = ep; | |
248 | |
249 ngx_memzero(&sev, sizeof(struct sigevent)); | |
250 sev.sigev_notify = SIGEV_PORT; | |
251 #if !(NGX_TEST_BUILD_EVENTPORT) | |
252 sev.sigev_value.sival_ptr = &pn; | |
253 #endif | |
254 | |
255 if (timer_create(CLOCK_REALTIME, &sev, &event_timer) == -1) { | |
256 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
257 "timer_create() failed"); | |
258 return NGX_ERROR; | |
259 } | |
260 | |
261 its.it_interval.tv_sec = timer / 1000; | |
262 its.it_interval.tv_nsec = (timer % 1000) * 1000000; | |
263 its.it_value.tv_sec = timer / 1000; | |
264 its.it_value.tv_nsec = (timer % 1000) * 1000000; | |
265 | |
266 if (timer_settime(event_timer, 0, &its, NULL) == -1) { | |
267 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
268 "timer_settime() failed"); | |
269 return NGX_ERROR; | |
270 } | |
271 | |
272 ngx_event_flags |= NGX_USE_TIMER_EVENT; | |
273 } | |
274 | |
275 nevents = epcf->events; | |
276 | |
277 ngx_io = ngx_os_io; | |
278 | |
279 ngx_event_actions = ngx_eventport_module_ctx.actions; | |
280 | |
281 return NGX_OK; | |
282 } | |
283 | |
284 | |
285 static void | |
286 ngx_eventport_done(ngx_cycle_t *cycle) | |
287 { | |
1870
a62fb6c156c5
fix building --test-build-rtsig and --test-build-eventport on FreeBSD 7
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
288 if (event_timer != (timer_t) -1) { |
719 | 289 if (timer_delete(event_timer) == -1) { |
290 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
291 "timer_delete() failed"); | |
292 } | |
293 | |
1870
a62fb6c156c5
fix building --test-build-rtsig and --test-build-eventport on FreeBSD 7
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
294 event_timer = (timer_t) -1; |
719 | 295 } |
296 | |
297 if (close(ep) == -1) { | |
298 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
299 "close() event port failed"); | |
300 } | |
301 | |
302 ep = -1; | |
303 | |
304 ngx_free(event_list); | |
305 | |
306 event_list = NULL; | |
307 nevents = 0; | |
308 } | |
309 | |
310 | |
311 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
|
312 ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) |
719 | 313 { |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
314 ngx_int_t events, prev; |
719 | 315 ngx_event_t *e; |
316 ngx_connection_t *c; | |
317 | |
318 c = ev->data; | |
319 | |
320 events = event; | |
321 | |
322 if (event == NGX_READ_EVENT) { | |
323 e = c->write; | |
324 prev = POLLOUT; | |
325 #if (NGX_READ_EVENT != POLLIN) | |
326 events = POLLIN; | |
327 #endif | |
328 | |
329 } else { | |
330 e = c->read; | |
331 prev = POLLIN; | |
332 #if (NGX_WRITE_EVENT != POLLOUT) | |
333 events = POLLOUT; | |
334 #endif | |
335 } | |
336 | |
337 if (e->oneshot) { | |
338 events |= prev; | |
339 } | |
340 | |
341 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
|
342 "eventport add event: fd:%d ev:%04Xi", c->fd, events); |
719 | 343 |
344 if (port_associate(ep, PORT_SOURCE_FD, c->fd, events, | |
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 ev->active = 1; | |
354 ev->oneshot = 1; | |
355 | |
356 return NGX_OK; | |
357 } | |
358 | |
359 | |
360 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
|
361 ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) |
719 | 362 { |
363 ngx_event_t *e; | |
364 ngx_connection_t *c; | |
365 | |
366 /* | |
367 * when the file descriptor is closed, the event port automatically | |
4572
67653855682e
Fixed spelling in multiline C comments.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
368 * dissociates it from the port, so we do not need to dissociate explicitly |
719 | 369 * the event before the closing the file descriptor |
370 */ | |
371 | |
372 if (flags & NGX_CLOSE_EVENT) { | |
373 ev->active = 0; | |
374 ev->oneshot = 0; | |
375 return NGX_OK; | |
376 } | |
377 | |
378 c = ev->data; | |
379 | |
380 if (event == NGX_READ_EVENT) { | |
381 e = c->write; | |
382 event = POLLOUT; | |
383 | |
384 } else { | |
385 e = c->read; | |
386 event = POLLIN; | |
387 } | |
388 | |
389 if (e->oneshot) { | |
390 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
|
391 "eventport change event: fd:%d ev:%04Xi", c->fd, event); |
719 | 392 |
393 if (port_associate(ep, PORT_SOURCE_FD, c->fd, event, | |
394 (void *) ((uintptr_t) ev | ev->instance)) | |
395 == -1) | |
396 { | |
397 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
398 "port_associate() failed"); | |
399 return NGX_ERROR; | |
400 } | |
401 | |
402 } else { | |
403 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
404 "eventport del event: fd:%d", c->fd); | |
405 | |
406 if (port_dissociate(ep, PORT_SOURCE_FD, c->fd) == -1) { | |
407 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
408 "port_dissociate() failed"); | |
409 return NGX_ERROR; | |
410 } | |
411 } | |
412 | |
413 ev->active = 0; | |
414 ev->oneshot = 0; | |
415 | |
416 return NGX_OK; | |
417 } | |
418 | |
419 | |
6021
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
420 static ngx_int_t |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
421 ngx_eventport_notify(ngx_event_handler_pt handler) |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
422 { |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
423 notify_event.handler = handler; |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
424 |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
425 if (port_send(ep, 0, ¬ify_event) != 0) { |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
426 ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno, |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
427 "port_send() failed"); |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
428 return NGX_ERROR; |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
429 } |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
430 |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
431 return NGX_OK; |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
432 } |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
433 |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
434 |
6923
fbdaad9b0e7b
Added missing "static" specifiers found by gcc -Wtraditional.
Ruslan Ermilov <ru@nginx.com>
parents:
6922
diff
changeset
|
435 static ngx_int_t |
719 | 436 ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
437 ngx_uint_t flags) | |
438 { | |
439 int n, revents; | |
440 u_int events; | |
441 ngx_err_t err; | |
442 ngx_int_t instance; | |
443 ngx_uint_t i, level; | |
5821
3f5f0ab59b35
Events: processing of posted events changed from LIFO to FIFO.
Valentin Bartenev <vbart@nginx.com>
parents:
5820
diff
changeset
|
444 ngx_event_t *ev, *rev, *wev; |
3f5f0ab59b35
Events: processing of posted events changed from LIFO to FIFO.
Valentin Bartenev <vbart@nginx.com>
parents:
5820
diff
changeset
|
445 ngx_queue_t *queue; |
719 | 446 ngx_connection_t *c; |
447 struct timespec ts, *tp; | |
448 | |
449 if (timer == NGX_TIMER_INFINITE) { | |
450 tp = NULL; | |
451 | |
452 } else { | |
453 ts.tv_sec = timer / 1000; | |
454 ts.tv_nsec = (timer % 1000) * 1000000; | |
455 tp = &ts; | |
456 } | |
457 | |
458 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
459 "eventport timer: %M", timer); | |
460 | |
461 events = 1; | |
462 | |
1354
f69d1aab6a0f
make 64-bit ngx_int_t on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
1287
diff
changeset
|
463 n = port_getn(ep, event_list, (u_int) nevents, &events, tp); |
719 | 464 |
465 err = ngx_errno; | |
466 | |
467 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
|
468 ngx_time_update(); |
719 | 469 } |
470 | |
471 if (n == -1) { | |
472 if (err == ETIME) { | |
473 if (timer != NGX_TIMER_INFINITE) { | |
474 return NGX_OK; | |
475 } | |
476 | |
477 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
478 "port_getn() returned no events without timeout"); | |
479 return NGX_ERROR; | |
480 } | |
481 | |
482 level = (err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT; | |
483 ngx_log_error(level, cycle->log, err, "port_getn() failed"); | |
484 return NGX_ERROR; | |
485 } | |
486 | |
487 if (events == 0) { | |
488 if (timer != NGX_TIMER_INFINITE) { | |
489 return NGX_OK; | |
490 } | |
491 | |
492 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
493 "port_getn() returned no events without timeout"); | |
494 return NGX_ERROR; | |
495 } | |
496 | |
497 for (i = 0; i < events; i++) { | |
498 | |
499 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
|
500 ngx_time_update(); |
719 | 501 continue; |
502 } | |
503 | |
504 ev = event_list[i].portev_user; | |
505 | |
506 switch (event_list[i].portev_source) { | |
507 | |
508 case PORT_SOURCE_FD: | |
509 | |
510 instance = (uintptr_t) ev & 1; | |
511 ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1); | |
512 | |
513 if (ev->closed || ev->instance != instance) { | |
514 | |
515 /* | |
516 * the stale event from a file descriptor | |
517 * that was just closed in this iteration | |
518 */ | |
519 | |
520 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
521 "eventport: stale event %p", ev); | |
522 continue; | |
523 } | |
524 | |
525 revents = event_list[i].portev_events; | |
526 | |
527 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
528 "eventport: fd:%d, ev:%04Xd", | |
6479
dc92298b1852
Events: fixed logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6475
diff
changeset
|
529 (int) event_list[i].portev_object, revents); |
719 | 530 |
531 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
|
532 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
|
533 "port_getn() error fd:%d ev:%04Xd", |
6479
dc92298b1852
Events: fixed logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6475
diff
changeset
|
534 (int) event_list[i].portev_object, revents); |
719 | 535 } |
536 | |
537 if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { | |
538 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
539 "strange port_getn() events fd:%d ev:%04Xd", | |
6479
dc92298b1852
Events: fixed logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6475
diff
changeset
|
540 (int) event_list[i].portev_object, revents); |
719 | 541 } |
542 | |
6806
75dbab4ea930
Events: improved error event handling for UDP sockets.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6479
diff
changeset
|
543 if (revents & (POLLERR|POLLHUP|POLLNVAL)) { |
75dbab4ea930
Events: improved error event handling for UDP sockets.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6479
diff
changeset
|
544 |
719 | 545 /* |
6806
75dbab4ea930
Events: improved error event handling for UDP sockets.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6479
diff
changeset
|
546 * if the error events were returned, add POLLIN and POLLOUT |
75dbab4ea930
Events: improved error event handling for UDP sockets.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6479
diff
changeset
|
547 * to handle the events at least in one active handler |
719 | 548 */ |
549 | |
550 revents |= POLLIN|POLLOUT; | |
551 } | |
552 | |
553 c = ev->data; | |
554 rev = c->read; | |
555 wev = c->write; | |
556 | |
557 rev->active = 0; | |
558 wev->active = 0; | |
559 | |
560 if (revents & POLLIN) { | |
5820
3377f9459e99
Events: removed broken thread support from posted events.
Valentin Bartenev <vbart@nginx.com>
parents:
5175
diff
changeset
|
561 rev->ready = 1; |
719 | 562 |
563 if (flags & NGX_POST_EVENTS) { | |
5820
3377f9459e99
Events: removed broken thread support from posted events.
Valentin Bartenev <vbart@nginx.com>
parents:
5175
diff
changeset
|
564 queue = rev->accept ? &ngx_posted_accept_events |
3377f9459e99
Events: removed broken thread support from posted events.
Valentin Bartenev <vbart@nginx.com>
parents:
5175
diff
changeset
|
565 : &ngx_posted_events; |
719 | 566 |
5820
3377f9459e99
Events: removed broken thread support from posted events.
Valentin Bartenev <vbart@nginx.com>
parents:
5175
diff
changeset
|
567 ngx_post_event(rev, queue); |
719 | 568 |
569 } else { | |
570 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
|
571 |
5170
6362bd26e4b0
Events: protection from stale events in eventport and devpoll.
Valentin Bartenev <vbart@nginx.com>
parents:
4759
diff
changeset
|
572 if (ev->closed || ev->instance != instance) { |
1287
3dd9883fa121
fix segfault when event port returns POLLERR without POLLIN or POLLOUT
Igor Sysoev <igor@sysoev.ru>
parents:
1128
diff
changeset
|
573 continue; |
3dd9883fa121
fix segfault when event port returns POLLERR without POLLIN or POLLOUT
Igor Sysoev <igor@sysoev.ru>
parents:
1128
diff
changeset
|
574 } |
719 | 575 } |
576 | |
577 if (rev->accept) { | |
578 if (ngx_use_accept_mutex) { | |
579 ngx_accept_events = 1; | |
580 continue; | |
581 } | |
582 | |
583 if (port_associate(ep, PORT_SOURCE_FD, c->fd, POLLIN, | |
584 (void *) ((uintptr_t) ev | ev->instance)) | |
585 == -1) | |
586 { | |
587 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, | |
588 "port_associate() failed"); | |
589 return NGX_ERROR; | |
590 } | |
591 } | |
592 } | |
593 | |
594 if (revents & POLLOUT) { | |
5820
3377f9459e99
Events: removed broken thread support from posted events.
Valentin Bartenev <vbart@nginx.com>
parents:
5175
diff
changeset
|
595 wev->ready = 1; |
719 | 596 |
597 if (flags & NGX_POST_EVENTS) { | |
5820
3377f9459e99
Events: removed broken thread support from posted events.
Valentin Bartenev <vbart@nginx.com>
parents:
5175
diff
changeset
|
598 ngx_post_event(wev, &ngx_posted_events); |
719 | 599 |
600 } else { | |
601 wev->handler(wev); | |
602 } | |
603 } | |
604 | |
605 continue; | |
606 | |
6021
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
607 case PORT_SOURCE_USER: |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
608 |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
609 ev->handler(ev); |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
610 |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
611 continue; |
117c77b22db1
Events: implemented eventport notification mechanism.
Ruslan Ermilov <ru@nginx.com>
parents:
6018
diff
changeset
|
612 |
719 | 613 default: |
614 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
6005
d84f0abd4a53
Events: fixed typo in the error message.
Ruslan Ermilov <ru@nginx.com>
parents:
5821
diff
changeset
|
615 "unexpected eventport object %d", |
6479
dc92298b1852
Events: fixed logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6475
diff
changeset
|
616 (int) event_list[i].portev_object); |
719 | 617 continue; |
618 } | |
619 } | |
620 | |
621 return NGX_OK; | |
622 } | |
623 | |
624 | |
625 static void * | |
626 ngx_eventport_create_conf(ngx_cycle_t *cycle) | |
627 { | |
628 ngx_eventport_conf_t *epcf; | |
629 | |
630 epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t)); | |
631 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
|
632 return NULL; |
719 | 633 } |
634 | |
635 epcf->events = NGX_CONF_UNSET; | |
636 | |
637 return epcf; | |
638 } | |
639 | |
640 | |
641 static char * | |
642 ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf) | |
643 { | |
644 ngx_eventport_conf_t *epcf = conf; | |
645 | |
646 ngx_conf_init_uint_value(epcf->events, 32); | |
647 | |
648 return NGX_CONF_OK; | |
649 } |