Deregister EVFILT_WRITE to avoid spinning with serial ports.
diff --git a/asio/include/asio/detail/impl/kqueue_reactor.ipp b/asio/include/asio/detail/impl/kqueue_reactor.ipp
index ae3087e..0482c46 100644
--- a/asio/include/asio/detail/impl/kqueue_reactor.ipp
+++ b/asio/include/asio/detail/impl/kqueue_reactor.ipp
@@ -384,6 +384,20 @@
descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr);
mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+ if (events[i].filter == EVFILT_WRITE
+ && descriptor_data->op_queue_[write_op].empty())
+ {
+ // Some descriptor types, like serial ports, don't seem to support
+ // EV_CLEAR with EVFILT_WRITE. Since we have no pending write
+ // operations we'll remove the EVFILT_WRITE registration here so that
+ // we don't end up in a tight spin.
+ struct kevent delete_events[1];
+ ASIO_KQUEUE_EV_SET(&delete_events[0],
+ descriptor_data->descriptor_, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
+ ::kevent(kqueue_fd_, delete_events, 1, 0, 0, 0);
+ descriptor_data->num_kevents_ = 1;
+ }
+
// Exception operations must be processed first to ensure that any
// out-of-band data is read before normal data.
#if defined(__NetBSD__)