Mercurial > hg > nginx-quic
comparison src/event/modules/ngx_epoll_module.c @ 381:02a511569afb
nginx-0.0.7-2004-07-07-19:01:00 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 07 Jul 2004 15:01:00 +0000 |
parents | 5ce6561246a5 |
children | 537de4dca8ca |
comparison
equal
deleted
inserted
replaced
380:5ce6561246a5 | 381:02a511569afb |
---|---|
73 static int ngx_epoll_init(ngx_cycle_t *cycle); | 73 static int ngx_epoll_init(ngx_cycle_t *cycle); |
74 static void ngx_epoll_done(ngx_cycle_t *cycle); | 74 static void ngx_epoll_done(ngx_cycle_t *cycle); |
75 static int ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags); | 75 static int ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags); |
76 static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags); | 76 static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags); |
77 static int ngx_epoll_add_connection(ngx_connection_t *c); | 77 static int ngx_epoll_add_connection(ngx_connection_t *c); |
78 static int ngx_epoll_del_connection(ngx_connection_t *c); | 78 static int ngx_epoll_del_connection(ngx_connection_t *c, u_int flags); |
79 static int ngx_epoll_process_events(ngx_cycle_t *cycle); | 79 static int ngx_epoll_process_events(ngx_cycle_t *cycle); |
80 | 80 |
81 static void *ngx_epoll_create_conf(ngx_cycle_t *cycle); | 81 static void *ngx_epoll_create_conf(ngx_cycle_t *cycle); |
82 static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf); | 82 static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf); |
83 | 83 |
109 { | 109 { |
110 ngx_epoll_add_event, /* add an event */ | 110 ngx_epoll_add_event, /* add an event */ |
111 ngx_epoll_del_event, /* delete an event */ | 111 ngx_epoll_del_event, /* delete an event */ |
112 ngx_epoll_add_event, /* enable an event */ | 112 ngx_epoll_add_event, /* enable an event */ |
113 ngx_epoll_del_event, /* disable an event */ | 113 ngx_epoll_del_event, /* disable an event */ |
114 NULL, /* add an connection */ | 114 ngx_epoll_add_connection, /* add an connection */ |
115 NULL, /* delete an connection */ | 115 ngx_epoll_del_connection, /* delete an connection */ |
116 NULL, /* process the changes */ | 116 NULL, /* process the changes */ |
117 ngx_epoll_process_events, /* process the events */ | 117 ngx_epoll_process_events, /* process the events */ |
118 ngx_epoll_init, /* init the events */ | 118 ngx_epoll_init, /* init the events */ |
119 ngx_epoll_done, /* done the events */ | 119 ngx_epoll_done, /* done the events */ |
120 } | 120 } |
122 | 122 |
123 ngx_module_t ngx_epoll_module = { | 123 ngx_module_t ngx_epoll_module = { |
124 NGX_MODULE, | 124 NGX_MODULE, |
125 &ngx_epoll_module_ctx, /* module context */ | 125 &ngx_epoll_module_ctx, /* module context */ |
126 ngx_epoll_commands, /* module directives */ | 126 ngx_epoll_commands, /* module directives */ |
127 NGX_EVENT_MODULE, /* module type */ | 127 NGX_EVENT_MODULE, /* module type */ |
128 NULL, /* init module */ | 128 NULL, /* init module */ |
129 NULL /* init process */ | 129 NULL /* init process */ |
130 }; | 130 }; |
131 | 131 |
132 | 132 |
133 static int ngx_epoll_init(ngx_cycle_t *cycle) | 133 static int ngx_epoll_init(ngx_cycle_t *cycle) |
134 { | 134 { |
172 ngx_event_flags = NGX_USE_CLEAR_EVENT | 172 ngx_event_flags = NGX_USE_CLEAR_EVENT |
173 #else | 173 #else |
174 ngx_event_flags = NGX_USE_LEVEL_EVENT | 174 ngx_event_flags = NGX_USE_LEVEL_EVENT |
175 #endif | 175 #endif |
176 |NGX_HAVE_GREEDY_EVENT | 176 |NGX_HAVE_GREEDY_EVENT |
177 |NGX_HAVE_INSTANCE_EVENT; | 177 |NGX_USE_EPOLL_EVENT; |
178 | 178 |
179 return NGX_OK; | 179 return NGX_OK; |
180 } | 180 } |
181 | 181 |
182 | 182 |
304 | 304 |
305 return NGX_OK; | 305 return NGX_OK; |
306 } | 306 } |
307 | 307 |
308 | 308 |
309 #if 0 | |
310 static int ngx_epoll_add_connection(ngx_connection_t *c) | 309 static int ngx_epoll_add_connection(ngx_connection_t *c) |
311 { | 310 { |
312 struct epoll_event ee; | 311 struct epoll_event ee; |
313 | 312 |
314 ee.events = EPOLLIN|EPOLLOUT|EPOLLET; | 313 ee.events = EPOLLIN|EPOLLOUT|EPOLLET; |
328 | 327 |
329 return NGX_OK; | 328 return NGX_OK; |
330 } | 329 } |
331 | 330 |
332 | 331 |
333 static int ngx_epoll_del_connection(ngx_connection_t *c) | 332 static int ngx_epoll_del_connection(ngx_connection_t *c, u_int flags) |
334 { | 333 { |
334 int op; | |
335 struct epoll_event ee; | |
336 | |
337 /* | |
338 * when the file descriptor is closed the epoll automatically deletes | |
339 * it from its queue so we do not need to delete explicity the event | |
340 * before the closing the file descriptor | |
341 */ | |
342 | |
343 if (flags & NGX_CLOSE_EVENT) { | |
344 c->read->active = 0; | |
345 c->write->active = 0; | |
346 return NGX_OK; | |
347 } | |
348 | |
349 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
350 "epoll del connection: fd:%d", c->fd); | |
351 | |
352 op = EPOLL_CTL_DEL; | |
353 ee.events = 0; | |
354 ee.data.ptr = NULL; | |
355 | |
356 if (epoll_ctl(ep, op, c->fd, &ee) == -1) { | |
357 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
358 "epoll_ctl(%d, %d) failed", op, c->fd); | |
359 return NGX_ERROR; | |
360 } | |
361 | |
335 c->read->active = 0; | 362 c->read->active = 0; |
336 c->write->active = 0; | 363 c->write->active = 0; |
337 | 364 |
338 return NGX_OK; | 365 return NGX_OK; |
339 } | 366 } |
340 #endif | |
341 | 367 |
342 | 368 |
343 int ngx_epoll_process_events(ngx_cycle_t *cycle) | 369 int ngx_epoll_process_events(ngx_cycle_t *cycle) |
344 { | 370 { |
345 int events; | 371 int events; |
347 ngx_int_t instance, i; | 373 ngx_int_t instance, i; |
348 ngx_uint_t lock, accept_lock, expire; | 374 ngx_uint_t lock, accept_lock, expire; |
349 ngx_err_t err; | 375 ngx_err_t err; |
350 ngx_log_t *log; | 376 ngx_log_t *log; |
351 ngx_msec_t timer; | 377 ngx_msec_t timer; |
378 ngx_event_t *rev, *wev; | |
352 struct timeval tv; | 379 struct timeval tv; |
353 ngx_connection_t *c; | 380 ngx_connection_t *c; |
354 ngx_epoch_msec_t delta; | 381 ngx_epoch_msec_t delta; |
355 | 382 |
356 for ( ;; ) { | 383 for ( ;; ) { |
357 timer = ngx_event_find_timer(); | 384 timer = ngx_event_find_timer(); |
358 | 385 |
386 #if (NGX_THREADS) | |
387 | |
388 if (timer == NGX_TIMER_ERROR) { | |
389 return NGX_ERROR; | |
390 } | |
391 | |
392 if (timer == NGX_TIMER_INFINITE || timer > 500) { | |
393 timer = 500; | |
394 break; | |
395 } | |
396 | |
397 #endif | |
398 | |
359 if (timer != 0) { | 399 if (timer != 0) { |
360 break; | 400 break; |
361 } | 401 } |
362 | 402 |
363 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 403 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
364 "epoll expired timer"); | 404 "epoll expired timer"); |
365 | 405 |
366 ngx_event_expire_timers((ngx_msec_t) | 406 ngx_event_expire_timers((ngx_msec_t) |
367 (ngx_elapsed_msec - ngx_old_elapsed_msec)); | 407 (ngx_elapsed_msec - ngx_old_elapsed_msec)); |
408 | |
409 if (ngx_posted_events && ngx_threaded) { | |
410 ngx_wakeup_worker_thread(cycle); | |
411 } | |
368 } | 412 } |
369 | 413 |
370 /* NGX_TIMER_INFINITE == INFTIM */ | 414 /* NGX_TIMER_INFINITE == INFTIM */ |
371 | 415 |
372 if (timer == NGX_TIMER_INFINITE) { | 416 if (timer == NGX_TIMER_INFINITE) { |
436 cycle->log, err, "epoll_wait() failed"); | 480 cycle->log, err, "epoll_wait() failed"); |
437 ngx_accept_mutex_unlock(); | 481 ngx_accept_mutex_unlock(); |
438 return NGX_ERROR; | 482 return NGX_ERROR; |
439 } | 483 } |
440 | 484 |
441 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | 485 if (events > 0) { |
442 ngx_accept_mutex_unlock(); | 486 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { |
443 return NGX_ERROR; | 487 ngx_accept_mutex_unlock(); |
444 } | 488 return NGX_ERROR; |
445 | 489 } |
446 lock = 1; | 490 |
491 lock = 1; | |
492 | |
493 } else { | |
494 lock =0; | |
495 } | |
496 | |
447 log = cycle->log; | 497 log = cycle->log; |
448 | 498 |
449 for (i = 0; i < events; i++) { | 499 for (i = 0; i < events; i++) { |
450 c = event_list[i].data.ptr; | 500 c = event_list[i].data.ptr; |
451 | 501 |
452 instance = (uintptr_t) c & 1; | 502 instance = (uintptr_t) c & 1; |
453 c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1); | 503 c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1); |
454 | 504 |
455 if (event_list[i].events & EPOLLIN) { | 505 rev = c->read; |
456 c->read->returned_instance = instance; | 506 |
457 } | 507 if (c->fd == -1 || rev->instance != instance) { |
458 | |
459 if (event_list[i].events & EPOLLOUT) { | |
460 c->write->returned_instance = instance; | |
461 } | |
462 | |
463 if (c->read->instance != instance) { | |
464 | 508 |
465 /* | 509 /* |
466 * the stale event from a file descriptor | 510 * the stale event from a file descriptor |
467 * that was just closed in this iteration | 511 * that was just closed in this iteration |
468 */ | 512 */ |
490 ngx_log_error(NGX_LOG_ALERT, log, 0, | 534 ngx_log_error(NGX_LOG_ALERT, log, 0, |
491 "strange epoll_wait() events fd:%d ev:%04X", | 535 "strange epoll_wait() events fd:%d ev:%04X", |
492 c->fd, event_list[i].events); | 536 c->fd, event_list[i].events); |
493 } | 537 } |
494 | 538 |
539 wev = c->write; | |
540 | |
495 if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)) | 541 if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)) |
496 && c->write->active) | 542 && wev->active) |
497 { | 543 { |
498 c->write->ready = 1; | 544 if (ngx_threaded) { |
499 | 545 wev->posted_ready = 1; |
500 if (!ngx_threaded && !ngx_accept_mutex_held) { | 546 ngx_post_event(wev); |
501 c->write->event_handler(c->write); | |
502 | 547 |
503 } else { | 548 } else { |
504 ngx_post_event(c->write); | 549 wev->ready = 1; |
550 | |
551 if (!ngx_accept_mutex_held) { | |
552 wev->event_handler(wev); | |
553 | |
554 } else { | |
555 ngx_post_event(wev); | |
556 } | |
505 } | 557 } |
506 } | 558 } |
507 | 559 |
508 /* | 560 /* |
509 * EPOLLIN must be handled after EPOLLOUT because we use | 561 * EPOLLIN must be handled after EPOLLOUT because we use |
510 * the optimization to avoid the unnecessary mutex locking/unlocking | 562 * the optimization to avoid the unnecessary mutex locking/unlocking |
511 * if the accept event is the last one. | 563 * if the accept event is the last one. |
512 */ | 564 */ |
513 | 565 |
514 if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)) | 566 if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)) |
515 && c->read->active) | 567 && rev->active) |
516 { | 568 { |
517 c->read->ready = 1; | 569 if (ngx_threaded && !rev->accept) { |
570 rev->posted_ready = 1; | |
571 | |
572 ngx_post_event(rev); | |
573 | |
574 continue; | |
575 } | |
576 | |
577 rev->ready = 1; | |
518 | 578 |
519 if (!ngx_threaded && !ngx_accept_mutex_held) { | 579 if (!ngx_threaded && !ngx_accept_mutex_held) { |
520 c->read->event_handler(c->read); | 580 rev->event_handler(rev); |
521 | 581 |
522 } else if (!c->read->accept) { | 582 } else if (!rev->accept) { |
523 ngx_post_event(c->read); | 583 ngx_post_event(rev); |
524 | 584 |
525 } else if (ngx_accept_disabled <= 0) { | 585 } else if (ngx_accept_disabled <= 0) { |
526 | 586 |
527 ngx_mutex_unlock(ngx_posted_events_mutex); | 587 ngx_mutex_unlock(ngx_posted_events_mutex); |
528 | 588 |
529 c->read->event_handler(c->read); | 589 rev->event_handler(rev); |
530 | 590 |
531 if (ngx_accept_disabled > 0) { | 591 if (ngx_accept_disabled > 0) { |
532 ngx_accept_mutex_unlock(); | 592 ngx_accept_mutex_unlock(); |
533 accept_lock = 0; | 593 accept_lock = 0; |
534 } | 594 } |
558 | 618 |
559 if (expire && delta) { | 619 if (expire && delta) { |
560 ngx_event_expire_timers((ngx_msec_t) delta); | 620 ngx_event_expire_timers((ngx_msec_t) delta); |
561 } | 621 } |
562 | 622 |
563 if (!ngx_threaded) { | 623 if (ngx_posted_events) { |
564 ngx_event_process_posted(cycle); | 624 if (ngx_threaded) { |
625 ngx_wakeup_worker_thread(cycle); | |
626 | |
627 } else { | |
628 ngx_event_process_posted(cycle); | |
629 } | |
565 } | 630 } |
566 | 631 |
567 return NGX_OK; | 632 return NGX_OK; |
568 } | 633 } |
569 | 634 |