You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2013/09/23 21:52:20 UTC
[06/20] git commit: TS-2187: use nonblock eventfd in EventNotify
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 <qi...@taobao.com>
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/5.0.x
Commit: 9a6fc2ab6b3147e82dfc229a7158083371d5545e
Parents: 40212d2
Author: Yunkai Zhang <qi...@taobao.com>
Authored: Sun Sep 8 23:35:39 2013 +0800
Committer: Yunkai Zhang <qi...@taobao.com>
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);