Package: libboost1.37-dev Version: 1.37.0-5+b1 Severity: important Tags: upstream patch
Hi, a lot of deluge and qbittorrent users (rdeps of libtorrent-rasterbar, which is in turn a rdep of boost1.37) reported[0] a bug related to the asio library included in libboost1.37-dev. The bug is related to the following traceback (similar with both clients): [...] RuntimeError: eventfd_select_interrupter: Function not implemented and prevents clients from starting, making the packages unusable. It has been reported only on debian amd64 systems (debian is likely the only distribution which actually builds libtorrent-rasterbar against boost1.37, but I don't know if the bug affects all 64bit systems). It has been reported upstream at: https://svn.boost.org/trac/boost/ticket/2683 and fixed with the following svn commit: https://svn.boost.org/trac/boost/changeset/50961 New boost1.38 is not affected by this bug, as mentioned in upstream changelog. I've rebuilt boost1.37 packages applying such patch and users confirmed me it works well. Could you please add the following patch (quilt ready) to the official packages so that we can fix this severe bug while waiting for boost1.38? Thanks, Cristian [0] The bug has been filed on debian bts: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=519036 on launchpad: https://bugs.launchpad.net/qbittorrent/+bug/341968 on deluge upstream support forum: http://forum.deluge-torrent.org/search.php?keywords=eventfd and boost bug tracker: https://svn.boost.org/trac/boost/ticket/2683 -- System Information: Debian Release: squeeze/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.28-1-686 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages libboost1.37-dev depends on: ii libboost-math1.37-dev 1.37.0-5+b1 Boost.Math Library development fil ii libboost-serialization1.37-d 1.37.0-5+b1 serialization library for C++ ii libc6 2.9-4 GNU C Library: Shared libraries ii libgcc1 1:4.3.3-5 GCC support library ii libicu40 4.0.1-2 International Components for Unico ii libstdc++6 4.3.3-5 The GNU Standard C++ Library v3 ii libstdc++6-4.3-dev [libstdc+ 4.3.3-5 The GNU Standard C++ Library v3 (d Versions of packages libboost1.37-dev recommends: ii libboost-date-time1.37-dev 1.37.0-5+b1 set of date-time libraries based o ii libboost-filesystem1.37-dev 1.37.0-5+b1 filesystem operations (portable pa pn libboost-graph1.37-dev <none> (no description available) pn libboost-iostreams1.37-dev <none> (no description available) pn libboost-mpi1.37-dev <none> (no description available) ii libboost-program-options1.37 1.37.0-5+b1 program options library for C++ ii libboost-python1.37-dev 1.37.0-5+b1 Boost.Python Library development f ii libboost-regex1.37-dev 1.37.0-5+b1 regular expression library for C++ ii libboost-signals1.37-dev 1.37.0-5+b1 managed signals and slots library ii libboost-system1.37-dev 1.37.0-5+b1 Operating system (e.g. diagnostics pn libboost-test1.37-dev <none> (no description available) ii libboost-thread1.37-dev 1.37.0-5+b1 portable C++ multi-threading pn libboost-wave1.37-dev <none> (no description available) pn libboost1.37-doc <none> (no description available) libboost1.37-dev suggests no packages. -- no debconf information
Use a pipe if eventfd is not supported at runtime. Reported upstream as https://svn.boost.org/trac/boost/ticket/2683 Fixed upstream at https://svn.boost.org/trac/boost/changeset/50961 --- boost_1_37_0.orig/boost/asio/detail/eventfd_select_interrupter.hpp +++ boost_1_37_0/boost/asio/detail/eventfd_select_interrupter.hpp @@ -58,9 +58,9 @@ eventfd_select_interrupter() { #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 - read_descriptor_ = syscall(__NR_eventfd, 0); + write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0); #else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 - read_descriptor_ = ::eventfd(0, 0); + write_descriptor_ = read_descriptor_ = ::eventfd(0, 0); #endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 if (read_descriptor_ != -1) { @@ -68,16 +68,29 @@ } else { - boost::system::error_code ec(errno, - boost::asio::error::get_system_category()); - boost::system::system_error e(ec, "eventfd_select_interrupter"); - boost::throw_exception(e); + int pipe_fds[2]; + if (pipe(pipe_fds) == 0) + { + read_descriptor_ = pipe_fds[0]; + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + write_descriptor_ = pipe_fds[1]; + ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + boost::system::system_error e(ec, "eventfd_select_interrupter"); + boost::throw_exception(e); + } } } // Destructor. ~eventfd_select_interrupter() { + if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_) + ::close(write_descriptor_); if (read_descriptor_ != -1) ::close(read_descriptor_); } @@ -86,17 +99,30 @@ void interrupt() { uint64_t counter(1UL); - ::write(read_descriptor_, &counter, sizeof(uint64_t)); + ::write(write_descriptor_, &counter, sizeof(uint64_t)); } // Reset the select interrupt. Returns true if the call was interrupted. bool reset() { - // Only perform one read. The kernel maintains an atomic counter. - uint64_t counter(0); - int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t)); - bool was_interrupted = (bytes_read > 0); - return was_interrupted; + if (write_descriptor_ == read_descriptor_) + { + // Only perform one read. The kernel maintains an atomic counter. + uint64_t counter(0); + int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t)); + bool was_interrupted = (bytes_read > 0); + return was_interrupted; + } + else + { + // Clear all data from the pipe. + char data[1024]; + int bytes_read = ::read(read_descriptor_, data, sizeof(data)); + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = ::read(read_descriptor_, data, sizeof(data)); + return was_interrupted; + } } // Get the read descriptor to be passed to select. @@ -111,6 +137,12 @@ // 64bit value will be written on the other end of the connection and this // descriptor will become readable. int read_descriptor_; + + // The write end of a connection used to interrupt the select call. A single + // 64bit non-zero value may be written to this to wake up the select which is + // waiting for the other end to become readable. This descriptor will only + // differ from the read descriptor when a pipe is used. + int write_descriptor_; }; } // namespace detail
signature.asc
Description: Digital signature