|
Boost-Commit : |
From: chris_at_[hidden]
Date: 2008-08-08 10:47:58
Author: chris_kohlhoff
Date: 2008-08-08 10:47:58 EDT (Fri, 08 Aug 2008)
New Revision: 48031
URL: http://svn.boost.org/trac/boost/changeset/48031
Log:
Fix a tight spin on epoll (or /dev/poll) that occurs when the EPOLLERR and
EPOLLHUP events are reported for a descriptor and there are no pending
operations.
Text files modified:
trunk/boost/asio/detail/dev_poll_reactor.hpp | 15 ++++++++-------
trunk/boost/asio/detail/epoll_reactor.hpp | 15 ++++++++-------
2 files changed, 16 insertions(+), 14 deletions(-)
Modified: trunk/boost/asio/detail/dev_poll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/dev_poll_reactor.hpp (original)
+++ trunk/boost/asio/detail/dev_poll_reactor.hpp 2008-08-08 10:47:58 EDT (Fri, 08 Aug 2008)
@@ -423,14 +423,15 @@
else
more_writes = write_op_queue_.has_operation(descriptor);
- if ((events[i].events == POLLHUP)
- && !more_except && !more_reads && !more_writes)
+ if ((events[i].events & (POLLERR | POLLHUP)) != 0
+ && (events[i].events & ~(POLLERR | POLLHUP)) == 0
+ && !more_except && !more_reads && !more_writes)
{
- // If we have only an POLLHUP event and no operations associated
- // with the descriptor then we need to delete the descriptor from
- // /dev/poll. The poll operation might produce POLLHUP events even
- // if they are not specifically requested, so if we do not remove the
- // descriptor we can end up in a tight polling loop.
+ // If we have an event and no operations associated with the
+ // descriptor then we need to delete the descriptor from /dev/poll.
+ // The poll operation can produce POLLHUP or POLLERR events when there
+ // is no operation pending, so if we do not remove the descriptor we
+ // can end up in a tight polling loop.
::pollfd ev = { 0 };
ev.fd = descriptor;
ev.events = POLLREMOVE;
Modified: trunk/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor.hpp (original)
+++ trunk/boost/asio/detail/epoll_reactor.hpp 2008-08-08 10:47:58 EDT (Fri, 08 Aug 2008)
@@ -497,14 +497,15 @@
else
more_writes = write_op_queue_.has_operation(descriptor);
- if ((events[i].events == EPOLLHUP)
- && !more_except && !more_reads && !more_writes)
+ if ((events[i].events & (EPOLLERR | EPOLLHUP)) != 0
+ && (events[i].events & ~(EPOLLERR | EPOLLHUP)) == 0
+ && !more_except && !more_reads && !more_writes)
{
- // If we have only an EPOLLHUP event and no operations associated
- // with the descriptor then we need to delete the descriptor from
- // epoll. The epoll_wait system call will produce EPOLLHUP events
- // even if they are not specifically requested, so if we do not
- // remove the descriptor we can end up in a tight loop of repeated
+ // If we have an event and no operations associated with the
+ // descriptor then we need to delete the descriptor from epoll. The
+ // epoll_wait system call can produce EPOLLHUP or EPOLLERR events
+ // when there is no operation pending, so if we do not remove the
+ // descriptor we can end up in a tight loop of repeated
// calls to epoll_wait.
epoll_event ev = { 0, { 0 } };
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk