9eb6f2e38dc0103bd0d64a17221e2cc59b8cb138 changed epoll() not to pass "unknown"
bits to the file implementation's poll() method. This had a worthy cause:
issue #971 was caused by unknown bits which got to poll_no_poll() which in
turn complained about them.

However, this change caused a new regression in EPOLLET on sockets (see
issue #974 reporting this regression). The socket's poll function relies
on knowing whether EPOLLET is being used, because it needs to avoid an
optimization which would cause missed wakeups with EPOLLET (see commit
d41d748f89cf6e47820e8585cef6eedb837c05be for more information). So although
the EPOLLET bit is *not* traditionally supported by the poll() method, we
in OSv we do need to pass it on to poll(). Other bits, namely EPOLLONESHOT,
we still don't need to pass.

Fixes #974.

Signed-off-by: Nadav Har'El <n...@scylladb.com>
---
 core/epoll.cc | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/core/epoll.cc b/core/epoll.cc
index 422a8170..71530483 100644
--- a/core/epoll.cc
+++ b/core/epoll.cc
@@ -30,26 +30,28 @@ TRACEPOINT(trace_epoll_ctl, "epfd=%d, fd=%d, op=%s 
event=0x%x", int, int, const
 TRACEPOINT(trace_epoll_wait, "epfd=%d, maxevents=%d, timeout=%d", int, int, 
int);
 TRACEPOINT(trace_epoll_ready, "fd=%d file=%p, event=0x%x", int, file*, int);
 
-// We implement epoll using poll(), and therefore need to convert epoll's
-// event bits to and poll(). These are mostly the same, so the conversion
-// is trivial, but we verify this here with static_asserts. We additionally
-// support the epoll-only EPOLLET and EPOLLONESHOT, but those are not passed
-// on to poll() who wouldn't know what to do with them.
+// We implement epoll using the file's poll() method, and therefore need to
+// convert epoll's event bits to and poll ones. These are mostly the same,
+// so the conversion is trivial, but we verify this here with static_asserts.
+// We also pass the EPOLLET bit from epoll to poll because sockets' poll needs
+// to avoid a certain optimization (see sopoll_generic_locked()).
+// The remaining epoll-specific bit, EPOLLONESHOT, is not passed to poll().
 static_assert(POLLIN == EPOLLIN, "POLLIN!=EPOLLIN");
 static_assert(POLLOUT == EPOLLOUT, "POLLOUT!=EPOLLOUT");
 static_assert(POLLRDHUP == EPOLLRDHUP, "POLLRDHUP!=EPOLLRDHUP");
 static_assert(POLLPRI == EPOLLPRI, "POLLPRI!=EPOLLPRI");
 static_assert(POLLERR == EPOLLERR, "POLLERR!=EPOLLERR");
 static_assert(POLLHUP == EPOLLHUP, "POLLHUP!=EPOLLHUP");
-constexpr int SUPPORTED_EVENTS =
+constexpr int POLL_OUTPUTS =
         EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLPRI | EPOLLERR | EPOLLHUP;
+constexpr int POLL_INPUTS = POLL_OUTPUTS | EPOLLET;
 inline uint32_t events_epoll_to_poll(uint32_t e)
 {
-    return e & SUPPORTED_EVENTS;
+    return e & POLL_INPUTS;
 }
 inline uint32_t events_poll_to_epoll(uint32_t e)
 {
-    assert (!(e & ~SUPPORTED_EVENTS));
+    assert (!(e & ~POLL_OUTPUTS));
     return e;
 }
 
-- 
2.14.3

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to