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