comparison src/event/modules/ngx_epoll_module.c @ 5372:36b58ddb566d

Events: support for EPOLLRDHUP (ticket #320). Since Linux 2.6.17, epoll is able to report about peer half-closed connection using special EPOLLRDHUP flag on a read event.
author Valentin Bartenev <vbart@nginx.com>
date Fri, 12 Jul 2013 14:51:07 +0400
parents 4c36e15651f7
children 31dd63dcb9ea
comparison
equal deleted inserted replaced
5371:b95e70ae6bcd 5372:36b58ddb566d
22 #define EPOLLWRNORM 0x100 22 #define EPOLLWRNORM 0x100
23 #define EPOLLWRBAND 0x200 23 #define EPOLLWRBAND 0x200
24 #define EPOLLMSG 0x400 24 #define EPOLLMSG 0x400
25 #define EPOLLERR 0x008 25 #define EPOLLERR 0x008
26 #define EPOLLHUP 0x010 26 #define EPOLLHUP 0x010
27
28 #define EPOLLRDHUP 0x2000
27 29
28 #define EPOLLET 0x80000000 30 #define EPOLLET 0x80000000
29 #define EPOLLONESHOT 0x40000000 31 #define EPOLLONESHOT 0x40000000
30 32
31 #define EPOLL_CTL_ADD 1 33 #define EPOLL_CTL_ADD 1
394 events = (uint32_t) event; 396 events = (uint32_t) event;
395 397
396 if (event == NGX_READ_EVENT) { 398 if (event == NGX_READ_EVENT) {
397 e = c->write; 399 e = c->write;
398 prev = EPOLLOUT; 400 prev = EPOLLOUT;
399 #if (NGX_READ_EVENT != EPOLLIN) 401 #if (NGX_READ_EVENT != EPOLLIN|EPOLLRDHUP)
400 events = EPOLLIN; 402 events = EPOLLIN|EPOLLRDHUP;
401 #endif 403 #endif
402 404
403 } else { 405 } else {
404 e = c->read; 406 e = c->read;
405 prev = EPOLLIN; 407 prev = EPOLLIN|EPOLLRDHUP;
406 #if (NGX_WRITE_EVENT != EPOLLOUT) 408 #if (NGX_WRITE_EVENT != EPOLLOUT)
407 events = EPOLLOUT; 409 events = EPOLLOUT;
408 #endif 410 #endif
409 } 411 }
410 412
464 e = c->write; 466 e = c->write;
465 prev = EPOLLOUT; 467 prev = EPOLLOUT;
466 468
467 } else { 469 } else {
468 e = c->read; 470 e = c->read;
469 prev = EPOLLIN; 471 prev = EPOLLIN|EPOLLRDHUP;
470 } 472 }
471 473
472 if (e->active) { 474 if (e->active) {
473 op = EPOLL_CTL_MOD; 475 op = EPOLL_CTL_MOD;
474 ee.events = prev | (uint32_t) flags; 476 ee.events = prev | (uint32_t) flags;
499 static ngx_int_t 501 static ngx_int_t
500 ngx_epoll_add_connection(ngx_connection_t *c) 502 ngx_epoll_add_connection(ngx_connection_t *c)
501 { 503 {
502 struct epoll_event ee; 504 struct epoll_event ee;
503 505
504 ee.events = EPOLLIN|EPOLLOUT|EPOLLET; 506 ee.events = EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP;
505 ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance); 507 ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance);
506 508
507 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 509 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
508 "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events); 510 "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events);
509 511
664 revents |= EPOLLIN|EPOLLOUT; 666 revents |= EPOLLIN|EPOLLOUT;
665 } 667 }
666 668
667 if ((revents & EPOLLIN) && rev->active) { 669 if ((revents & EPOLLIN) && rev->active) {
668 670
671 #if (NGX_HAVE_EPOLLRDHUP)
672 if (revents & EPOLLRDHUP) {
673 rev->pending_eof = 1;
674 }
675 #endif
676
669 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) { 677 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
670 rev->posted_ready = 1; 678 rev->posted_ready = 1;
671 679
672 } else { 680 } else {
673 rev->ready = 1; 681 rev->ready = 1;