Boost logo

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