When speculative operations are disallowed we need to give kqueue a kick.
diff --git a/asio/include/asio/detail/impl/kqueue_reactor.ipp b/asio/include/asio/detail/impl/kqueue_reactor.ipp
index b11d226..11624e0 100644
--- a/asio/include/asio/detail/impl/kqueue_reactor.ipp
+++ b/asio/include/asio/detail/impl/kqueue_reactor.ipp
@@ -180,7 +180,7 @@
   source_descriptor_data = 0;
 }
 
-void kqueue_reactor::start_op(int op_type, socket_type /*descriptor*/,
+void kqueue_reactor::start_op(int op_type, socket_type descriptor,
     kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op,
     bool is_continuation, bool allow_speculative)
 {
@@ -202,18 +202,26 @@
   bool first = descriptor_data->op_queue_[op_type].empty();
   if (first)
   {
-    if (allow_speculative)
+    if (allow_speculative
+        && (op_type != read_op
+          || descriptor_data->op_queue_[except_op].empty()))
     {
-      if (op_type != read_op || descriptor_data->op_queue_[except_op].empty())
+      if (op->perform())
       {
-        if (op->perform())
-        {
-          descriptor_lock.unlock();
-          io_service_.post_immediate_completion(op, is_continuation);
-          return;
-        }
+        descriptor_lock.unlock();
+        io_service_.post_immediate_completion(op, is_continuation);
+        return;
       }
     }
+    else
+    {
+      struct kevent events[2];
+      ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ,
+          EV_ADD | EV_CLEAR, 0, 0, descriptor_data);
+      ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE,
+          EV_ADD | EV_CLEAR, 0, 0, descriptor_data);
+      ::kevent(kqueue_fd_, events, 2, 0, 0, 0);
+    }
   }
 
   descriptor_data->op_queue_[op_type].push(op);