Updated Branches: refs/heads/master 40212d2d1 -> 9a6fc2ab6
TS-2187: use nonblock eventfd in EventNotify 1) Use nonblock eventfd, so that we can tolerate write() failed with errno EAGANIN â which is acceptable as the signal receiver will be notified eventually in this case. 2) After using nonblock eventfd, read() will not block in wait(). So I use epoll_wait() to implement block behavior, just like timedwait(). 3) nonblock eventfd can fix a potential problem: if receiver didn't read() data immediately, senders might block in write(). Signed-off-by: Yunkai Zhang <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/9a6fc2ab Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/9a6fc2ab Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/9a6fc2ab Branch: refs/heads/master Commit: 9a6fc2ab6b3147e82dfc229a7158083371d5545e Parents: 40212d2 Author: Yunkai Zhang <[email protected]> Authored: Sun Sep 8 23:35:39 2013 +0800 Committer: Yunkai Zhang <[email protected]> Committed: Wed Sep 11 15:18:18 2013 +0800 ---------------------------------------------------------------------- CHANGES | 2 ++ lib/ts/EventNotify.cc | 42 +++++++++++++++++++++++++++++++----------- lib/ts/EventNotify.h | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9a6fc2ab/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index d042183..adeb534 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ -*- coding: utf-8 -*- Changes with Apache Traffic Server 4.1.0 + *) [TS-2187] failed assert `nr == sizeof(uint64_t)` in EventNotify::signal() + *) [TS-2206] The trafficserver RC script does not use absolute path to traffic_line binary. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9a6fc2ab/lib/ts/EventNotify.cc ---------------------------------------------------------------------- diff --git a/lib/ts/EventNotify.cc b/lib/ts/EventNotify.cc index 3a499b6..feb9ad8 100644 --- a/lib/ts/EventNotify.cc +++ b/lib/ts/EventNotify.cc @@ -32,6 +32,7 @@ #ifdef HAVE_EVENTFD #include <sys/eventfd.h> +#include <sys/fcntl.h> #include <sys/epoll.h> #endif @@ -41,11 +42,13 @@ EventNotify::EventNotify() int ret; struct epoll_event ev; - // Don't use noblock here! - m_event_fd = eventfd(0, EFD_CLOEXEC); + m_event_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); if (m_event_fd < 0) { - // EFD_CLOEXEC invalid in <= Linux 2.6.27 + // EFD_NONBLOCK/EFD_CLOEXEC invalid in <= Linux 2.6.27 m_event_fd = eventfd(0, 0); + + fcntl(m_event_fd, F_SETFD, FD_CLOEXEC); + fcntl(m_event_fd, F_SETFL, O_NONBLOCK); } ink_release_assert(m_event_fd != -1); @@ -69,23 +72,39 @@ EventNotify::signal(void) #ifdef HAVE_EVENTFD ssize_t nr; uint64_t value = 1; + // + // If the addition would cause the counterâs value of eventfd + // to exceed the maximum, write() will fail with the errno EAGAIN, + // which is acceptable as the receiver will be notified eventually. + // nr = write(m_event_fd, &value, sizeof(uint64_t)); - ink_release_assert(nr == sizeof(uint64_t)); #else ink_cond_signal(&m_cond); #endif } -void +int EventNotify::wait(void) { #ifdef HAVE_EVENTFD - ssize_t nr; + ssize_t nr, nr_fd; uint64_t value = 0; + struct epoll_event ev; + + do { + nr_fd = epoll_wait(m_epoll_fd, &ev, 1, -1); + } while (nr_fd == -1 && errno == EINTR); + + if (nr_fd == -1) + return errno; + nr = read(m_event_fd, &value, sizeof(uint64_t)); - ink_release_assert(nr == sizeof(uint64_t)); + if (nr == sizeof(uint64_t)) + return 0; + else + return errno; #else - ink_cond_wait(&m_cond, &m_mutex); + return ink_cond_wait(&m_cond, &m_mutex); #endif } @@ -115,9 +134,10 @@ EventNotify::timedwait(int timeout) // milliseconds return errno; nr = read(m_event_fd, &value, sizeof(uint64_t)); - ink_release_assert(nr == sizeof(uint64_t)); - - return 0; + if (nr == sizeof(uint64_t)) + return 0; + else + return errno; #else ink_timestruc abstime; ink_hrtime curtime; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9a6fc2ab/lib/ts/EventNotify.h ---------------------------------------------------------------------- diff --git a/lib/ts/EventNotify.h b/lib/ts/EventNotify.h index b74e3af..7223e6d 100644 --- a/lib/ts/EventNotify.h +++ b/lib/ts/EventNotify.h @@ -38,7 +38,7 @@ class EventNotify public: EventNotify(); void signal(void); - void wait(void); + int wait(void); int timedwait(int timeout); // milliseconds void lock(void); bool trylock(void);
