Drop back to using a pipe if eventfd is not available at runtime.
diff --git a/asio/include/asio/detail/eventfd_select_interrupter.hpp b/asio/include/asio/detail/eventfd_select_interrupter.hpp
index cb42362..40fd4d2 100644
--- a/asio/include/asio/detail/eventfd_select_interrupter.hpp
+++ b/asio/include/asio/detail/eventfd_select_interrupter.hpp
@@ -57,9 +57,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)
     {
@@ -67,16 +67,29 @@
     }
     else
     {
-      asio::error_code ec(errno,
-          asio::error::get_system_category());
-      asio::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
+      {
+        asio::error_code ec(errno,
+            asio::error::get_system_category());
+        asio::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_);
   }
@@ -85,18 +98,31 @@
   void interrupt()
   {
     uint64_t counter(1UL);
-    int result = ::write(read_descriptor_, &counter, sizeof(uint64_t));
+    int result = ::write(write_descriptor_, &counter, sizeof(uint64_t));
     (void)result;
   }
 
   // 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