Mercurial > hg > nginx-mail
comparison src/event/modules/ngx_poll_module.c @ 112:408f195b3482 NGINX_0_3_3
nginx 0.3.3
*) Change: the "bl" and "af" parameters of the "listen" directive was
renamed to the "backlog" and "accept_filter".
*) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen"
directive.
*) Change: the "$msec" log parameter does not require now the
additional the gettimeofday() system call.
*) Feature: the -t switch now tests the "listen" directives.
*) Bugfix: if the invalid address was specified in the "listen"
directive, then after the -HUP signal nginx left an open socket in
the CLOSED state.
*) Bugfix: the mime type may be incorrectly set to default value for
index file with variable in the name; bug appeared in 0.3.0.
*) Feature: the "timer_resolution" directive.
*) Feature: the millisecond "$upstream_response_time" log parameter.
*) Bugfix: a temporary file with client request body now is removed
just after the response header was transferred to a client.
*) Bugfix: OpenSSL 0.9.6 compatibility.
*) Bugfix: the SSL certificate and key file paths could not be relative.
*) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in
the ngx_imap_ssl_module.
*) Bugfix: the "ssl_protocols" directive allowed to specify the single
protocol only.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Oct 2005 00:00:00 +0400 |
parents | 45f7329b4bd0 |
children | e38f51cd0905 |
comparison
equal
deleted
inserted
replaced
111:a175b609c76d | 112:408f195b3482 |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 | 10 |
11 | 11 |
12 static ngx_int_t ngx_poll_init(ngx_cycle_t *cycle); | 12 static ngx_int_t ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer); |
13 static void ngx_poll_done(ngx_cycle_t *cycle); | 13 static void ngx_poll_done(ngx_cycle_t *cycle); |
14 static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags); | 14 static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags); |
15 static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags); | 15 static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags); |
16 static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle); | 16 static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
17 ngx_uint_t flags); | |
17 static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf); | 18 static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf); |
18 | 19 |
19 | 20 |
20 static struct pollfd *event_list; | 21 static struct pollfd *event_list; |
21 static int nevents; | 22 static int nevents; |
22 | |
23 #if 0 | |
24 static ngx_event_t **ready_index; | |
25 #endif | |
26 | |
27 static ngx_event_t *accept_events; | |
28 | 23 |
29 | 24 |
30 static ngx_str_t poll_name = ngx_string("poll"); | 25 static ngx_str_t poll_name = ngx_string("poll"); |
31 | 26 |
32 ngx_event_module_t ngx_poll_module_ctx = { | 27 ngx_event_module_t ngx_poll_module_ctx = { |
65 }; | 60 }; |
66 | 61 |
67 | 62 |
68 | 63 |
69 static ngx_int_t | 64 static ngx_int_t |
70 ngx_poll_init(ngx_cycle_t *cycle) | 65 ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer) |
71 { | 66 { |
72 struct pollfd *list; | 67 struct pollfd *list; |
73 | 68 |
74 if (event_list == NULL) { | 69 if (event_list == NULL) { |
75 nevents = 0; | 70 nevents = 0; |
89 ngx_memcpy(list, event_list, sizeof(ngx_event_t *) * nevents); | 84 ngx_memcpy(list, event_list, sizeof(ngx_event_t *) * nevents); |
90 ngx_free(event_list); | 85 ngx_free(event_list); |
91 } | 86 } |
92 | 87 |
93 event_list = list; | 88 event_list = list; |
94 | |
95 #if 0 | |
96 if (ready_index) { | |
97 ngx_free(ready_index); | |
98 } | |
99 | |
100 ready_index = ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n, | |
101 cycle->log); | |
102 if (ready_index == NULL) { | |
103 return NGX_ERROR; | |
104 } | |
105 #endif | |
106 } | 89 } |
107 | 90 |
108 ngx_io = ngx_os_io; | 91 ngx_io = ngx_os_io; |
109 | 92 |
110 ngx_event_actions = ngx_poll_module_ctx.actions; | 93 ngx_event_actions = ngx_poll_module_ctx.actions; |
111 | 94 |
112 ngx_event_flags = NGX_USE_LEVEL_EVENT | 95 ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT; |
113 |NGX_USE_ONESHOT_EVENT | |
114 |NGX_USE_FD_EVENT; | |
115 | 96 |
116 return NGX_OK; | 97 return NGX_OK; |
117 } | 98 } |
118 | 99 |
119 | 100 |
120 static void | 101 static void |
121 ngx_poll_done(ngx_cycle_t *cycle) | 102 ngx_poll_done(ngx_cycle_t *cycle) |
122 { | 103 { |
123 ngx_free(event_list); | 104 ngx_free(event_list); |
124 #if 0 | |
125 ngx_free(ready_index); | |
126 #endif | |
127 | 105 |
128 event_list = NULL; | 106 event_list = NULL; |
129 #if 0 | |
130 ready_index = NULL; | |
131 #endif | |
132 } | 107 } |
133 | 108 |
134 | 109 |
135 static ngx_int_t | 110 static ngx_int_t |
136 ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) | 111 ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) |
187 | 162 |
188 | 163 |
189 static ngx_int_t | 164 static ngx_int_t |
190 ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags) | 165 ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags) |
191 { | 166 { |
192 ngx_uint_t i; | 167 ngx_event_t *e; |
193 ngx_cycle_t **cycle; | 168 ngx_connection_t *c; |
194 ngx_event_t *e; | |
195 ngx_connection_t *c; | |
196 | 169 |
197 c = ev->data; | 170 c = ev->data; |
198 | 171 |
199 ev->active = 0; | 172 ev->active = 0; |
200 | 173 |
232 event_list[ev->index] = event_list[nevents]; | 205 event_list[ev->index] = event_list[nevents]; |
233 | 206 |
234 c = ngx_cycle->files[event_list[nevents].fd]; | 207 c = ngx_cycle->files[event_list[nevents].fd]; |
235 | 208 |
236 if (c->fd == -1) { | 209 if (c->fd == -1) { |
237 cycle = ngx_old_cycles.elts; | |
238 for (i = 0; i < ngx_old_cycles.nelts; i++) { | |
239 if (cycle[i] == NULL) { | |
240 continue; | |
241 } | |
242 c = cycle[i]->files[event_list[nevents].fd]; | |
243 if (c->fd != -1) { | |
244 break; | |
245 } | |
246 } | |
247 } | |
248 | |
249 if (c->fd == -1) { | |
250 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, | 210 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, |
251 "unexpected last event"); | 211 "unexpected last event"); |
252 | 212 |
253 } else { | 213 } else { |
254 if (c->read->index == (u_int) nevents) { | 214 if (c->read->index == (u_int) nevents) { |
273 return NGX_OK; | 233 return NGX_OK; |
274 } | 234 } |
275 | 235 |
276 | 236 |
277 static ngx_int_t | 237 static ngx_int_t |
278 ngx_poll_process_events(ngx_cycle_t *cycle) | 238 ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) |
279 { | 239 { |
280 int ready, revents; | 240 int ready, revents; |
281 ngx_err_t err; | 241 ngx_err_t err; |
282 ngx_int_t i, nready; | 242 ngx_int_t i, nready; |
283 ngx_uint_t n, found, lock; | 243 ngx_uint_t found, level; |
284 ngx_msec_t timer, delta; | 244 ngx_msec_t delta; |
285 ngx_cycle_t **old_cycle; | 245 ngx_event_t *ev, **queue; |
286 ngx_event_t *ev; | |
287 ngx_connection_t *c; | 246 ngx_connection_t *c; |
288 struct timeval tv; | |
289 | |
290 timer = ngx_event_find_timer(); | |
291 | 247 |
292 /* NGX_TIMER_INFINITE == INFTIM */ | 248 /* NGX_TIMER_INFINITE == INFTIM */ |
293 | 249 |
294 #if (NGX_DEBUG0) | 250 #if (NGX_DEBUG0) |
295 if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { | 251 if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { |
299 i, event_list[i].fd, event_list[i].events); | 255 i, event_list[i].fd, event_list[i].events); |
300 } | 256 } |
301 } | 257 } |
302 #endif | 258 #endif |
303 | 259 |
304 if (ngx_accept_mutex) { | |
305 if (ngx_accept_disabled > 0) { | |
306 ngx_accept_disabled--; | |
307 | |
308 } else { | |
309 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { | |
310 return NGX_ERROR; | |
311 } | |
312 | |
313 if (ngx_accept_mutex_held == 0 | |
314 && (timer == NGX_TIMER_INFINITE | |
315 || timer > ngx_accept_mutex_delay)) | |
316 { | |
317 timer = ngx_accept_mutex_delay; | |
318 } | |
319 } | |
320 } | |
321 | |
322 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %M", timer); | 260 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %M", timer); |
323 | 261 |
324 ready = poll(event_list, (u_int) nevents, (int) timer); | 262 ready = poll(event_list, (u_int) nevents, (int) timer); |
325 | 263 |
326 if (ready == -1) { | 264 if (ready == -1) { |
327 err = ngx_errno; | 265 err = ngx_errno; |
328 } else { | 266 } else { |
329 err = 0; | 267 err = 0; |
330 } | 268 } |
331 | 269 |
332 ngx_gettimeofday(&tv); | 270 delta = ngx_current_msec; |
333 ngx_time_update(tv.tv_sec); | 271 |
334 | 272 if (flags & NGX_UPDATE_TIME) { |
335 delta = ngx_current_time; | 273 ngx_time_update(0, 0); |
336 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; | 274 } |
337 | 275 |
338 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 276 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
339 "poll ready %d of %d", ready, nevents); | 277 "poll ready %d of %d", ready, nevents); |
340 | 278 |
341 if (err) { | 279 if (err) { |
342 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, | 280 if (err == NGX_EINTR) { |
343 cycle->log, err, "poll() failed"); | 281 |
344 ngx_accept_mutex_unlock(); | 282 if (ngx_event_timer_alarm) { |
283 ngx_event_timer_alarm = 0; | |
284 return NGX_OK; | |
285 } | |
286 | |
287 level = NGX_LOG_INFO; | |
288 | |
289 } else { | |
290 level = NGX_LOG_ALERT; | |
291 } | |
292 | |
293 ngx_log_error(level, cycle->log, err, "poll() failed"); | |
345 return NGX_ERROR; | 294 return NGX_ERROR; |
346 } | 295 } |
347 | 296 |
348 if (timer != NGX_TIMER_INFINITE) { | 297 if (timer != NGX_TIMER_INFINITE) { |
349 delta = ngx_current_time - delta; | 298 delta = ngx_current_msec - delta; |
350 | 299 |
351 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 300 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
352 "poll timer: %M, delta: %M", timer, delta); | 301 "poll timer: %M, delta: %M", timer, delta); |
353 } else { | 302 } else { |
354 if (ready == 0) { | 303 if (ready == 0) { |
355 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 304 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
356 "poll() returned no events without timeout"); | 305 "poll() returned no events without timeout"); |
357 ngx_accept_mutex_unlock(); | |
358 return NGX_ERROR; | 306 return NGX_ERROR; |
359 } | 307 } |
360 } | 308 } |
361 | 309 |
362 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | 310 if (ready == 0) { |
363 ngx_accept_mutex_unlock(); | 311 return NGX_OK; |
364 return NGX_ERROR; | 312 } |
365 } | 313 |
366 | 314 ngx_mutex_lock(ngx_posted_events_mutex); |
367 lock = 1; | 315 |
368 nready = 0; | 316 nready = 0; |
369 | 317 |
370 for (i = 0; i < nevents && ready; i++) { | 318 for (i = 0; i < nevents && ready; i++) { |
371 | 319 |
372 revents = event_list[i].revents; | 320 revents = event_list[i].revents; |
373 | 321 |
374 #if 0 | 322 #if 1 |
375 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 323 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
376 "poll: %d: fd:%d ev:%04Xd rev:%04Xd", | 324 "poll: %d: fd:%d ev:%04Xd rev:%04Xd", |
377 i, event_list[i].fd, event_list[i].events, revents); | 325 i, event_list[i].fd, event_list[i].events, revents); |
378 #else | 326 #else |
379 if (revents) { | 327 if (revents) { |
404 } | 352 } |
405 | 353 |
406 c = ngx_cycle->files[event_list[i].fd]; | 354 c = ngx_cycle->files[event_list[i].fd]; |
407 | 355 |
408 if (c->fd == -1) { | 356 if (c->fd == -1) { |
409 old_cycle = ngx_old_cycles.elts; | |
410 for (n = 0; n < ngx_old_cycles.nelts; n++) { | |
411 if (old_cycle[n] == NULL) { | |
412 continue; | |
413 } | |
414 c = old_cycle[n]->files[event_list[i].fd]; | |
415 if (c->fd != -1) { | |
416 break; | |
417 } | |
418 } | |
419 } | |
420 | |
421 if (c->fd == -1) { | |
422 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event"); | 357 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event"); |
423 | 358 |
424 /* | 359 /* |
425 * it is certainly our fault and it should be investigated, | 360 * it is certainly our fault and it should be investigated, |
426 * in the meantime we disable this event to avoid a CPU spinning | 361 * in the meantime we disable this event to avoid a CPU spinning |
451 | 386 |
452 if (revents & POLLIN) { | 387 if (revents & POLLIN) { |
453 found = 1; | 388 found = 1; |
454 | 389 |
455 ev = c->read; | 390 ev = c->read; |
456 ev->ready = 1; | 391 |
457 | 392 if ((flags & NGX_POST_THREAD_EVENTS) && !ev->accept) { |
458 if (ev->oneshot) { | 393 ev->posted_ready = 1; |
459 if (ev->timer_set) { | 394 |
460 ngx_del_timer(ev); | 395 } else { |
461 } | 396 ev->ready = 1; |
462 ngx_poll_del_event(ev, NGX_READ_EVENT, 0); | |
463 } | 397 } |
464 | 398 |
465 if (ev->accept) { | 399 queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events: |
466 ev->next = accept_events; | 400 &ngx_posted_events); |
467 accept_events = ev; | 401 ngx_locked_post_event(ev, queue); |
468 } else { | |
469 ngx_post_event(ev); | |
470 } | |
471 | |
472 #if 0 | |
473 ready_index[nready++] = c->read; | |
474 #endif | |
475 } | 402 } |
476 | 403 |
477 if (revents & POLLOUT) { | 404 if (revents & POLLOUT) { |
478 found = 1; | 405 found = 1; |
479 ev = c->write; | 406 ev = c->write; |
480 ev->ready = 1; | 407 |
481 | 408 if (flags & NGX_POST_THREAD_EVENTS) { |
482 if (ev->oneshot) { | 409 ev->posted_ready = 1; |
483 if (ev->timer_set) { | 410 |
484 ngx_del_timer(ev); | 411 } else { |
485 } | 412 ev->ready = 1; |
486 ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0); | |
487 } | 413 } |
488 | 414 |
489 ngx_post_event(ev); | 415 ngx_locked_post_event(ev, &ngx_posted_events); |
490 #if 0 | |
491 ready_index[nready++] = c->write; | |
492 #endif | |
493 } | 416 } |
494 | 417 |
495 if (found) { | 418 if (found) { |
496 ready--; | 419 ready--; |
497 continue; | 420 continue; |
498 } | 421 } |
499 } | 422 } |
500 | 423 |
501 #if 0 | 424 ngx_mutex_unlock(ngx_posted_events_mutex); |
502 for (i = 0; i < nready; i++) { | |
503 ev = ready_index[i]; | |
504 | |
505 if (!ev->active) { | |
506 continue; | |
507 } | |
508 | |
509 ev->ready = 1; | |
510 | |
511 if (ev->oneshot) { | |
512 if (ev->timer_set) { | |
513 ngx_del_timer(ev); | |
514 } | |
515 | |
516 if (ev->write) { | |
517 ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0); | |
518 } else { | |
519 ngx_poll_del_event(ev, NGX_READ_EVENT, 0); | |
520 } | |
521 } | |
522 | |
523 ev->handler(ev); | |
524 } | |
525 #endif | |
526 | |
527 ev = accept_events; | |
528 | |
529 for ( ;; ) { | |
530 | |
531 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
532 "accept event %p", ev); | |
533 | |
534 if (ev == NULL) { | |
535 break; | |
536 } | |
537 | |
538 ngx_mutex_unlock(ngx_posted_events_mutex); | |
539 | |
540 ev->handler(ev); | |
541 | |
542 if (ngx_accept_disabled > 0) { | |
543 lock = 0; | |
544 break; | |
545 } | |
546 | |
547 ev = ev->next; | |
548 | |
549 if (ev == NULL) { | |
550 lock = 0; | |
551 break; | |
552 } | |
553 | |
554 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | |
555 ngx_accept_mutex_unlock(); | |
556 return NGX_ERROR; | |
557 } | |
558 | |
559 } | |
560 | |
561 ngx_accept_mutex_unlock(); | |
562 accept_events = NULL; | |
563 | |
564 if (lock) { | |
565 ngx_mutex_unlock(ngx_posted_events_mutex); | |
566 } | |
567 | 425 |
568 if (ready != 0) { | 426 if (ready != 0) { |
569 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events"); | 427 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events"); |
570 } | |
571 | |
572 ngx_event_expire_timers(); | |
573 | |
574 if (!ngx_threaded) { | |
575 ngx_event_process_posted(cycle); | |
576 } | 428 } |
577 | 429 |
578 return nready; | 430 return nready; |
579 } | 431 } |
580 | 432 |