[Boost-bugs] [Boost C++ Libraries] #5045: epoll_reactor::update_timeout() uses incorrect interrupter if TIMERFD is not available

Subject: [Boost-bugs] [Boost C++ Libraries] #5045: epoll_reactor::update_timeout() uses incorrect interrupter if TIMERFD is not available
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2011-01-07 05:41:36


#5045: epoll_reactor::update_timeout() uses incorrect interrupter if TIMERFD is
not available
----------------------------------------+-----------------------------------
 Reporter: Andrew Mann <amann@…> | Owner: chris_kohlhoff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
  Version: Boost Development Trunk | Severity: Showstopper
 Keywords: |
----------------------------------------+-----------------------------------
 Fix:
 Change the final line of epoll_reactor::update_timeout() from:
 interrupter_.interrupt();

 to:
 interrupt();


 Description:

 The linux epoll implementation of ASIO creates a fifo pipe for
 interrupting the epoll_wait() during exceptional events such as a timed
 event. Unlike other implementations, the epoll implementation doesn't
 actually use a write to the pipe as the triggering mechanism. Instead, a
 single write is performed on construction and the pipe is never read.
 Subsequent triggering is handled by using epoll_ctl(fd, EPOLL_CTL_MOD, fd,
 EPOLLIN | EPOLLERR | EPOLLET) to effectively reset the event. While this
 appears to be undocumented functionality of epoll_ctl(), it does appear to
 work.

 However, since the code never reads from the FIFO pipe and the pipe has a
 maximum buffer of 65535 bytes in current linux kernels, it's vital that
 the pipe not continue to be written to. epoll_reactor::update_timeout()
 violates this in the code path where BOOST_ASIO_HAS_TIMERFD is not defined
 (linux kernels older than about 2.6.22) by calling
 interrupter_.interrupt() rather than epoll_reactor::interrupt() - which
 generates an interrupt event by writing a single byte to the pipe.

 After 65534 calls (less on earlier kernels) to update_timeout() on the
 same reactor the pipe will be full and future calls will be unable to
 write to the pipe, which causes the interrupt to not occur. In certain
 cases (such as a write-only service_io thread) this can manifest itself as
 extremely long periods of non-responsiveness.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/5045>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:05 UTC