Add limited support for regular file descriptors.
The epoll_reactor now supports the use of regular file descriptors with
posix::stream_descriptor, provided the I/O operations on them never fail
with EAGAIN or EWOULDBLOCK. If the descriptor cannot be added to the
epoll set using epoll_ctl, and errno is EPERM (indicating an unsupported
descriptor type), then no error condition is raised. Instead, any
operation which would require a trip through the reactor will fail.
diff --git a/asio/include/asio/detail/impl/epoll_reactor.ipp b/asio/include/asio/detail/impl/epoll_reactor.ipp
index d28a91d..b8f1eb3 100644
--- a/asio/include/asio/detail/impl/epoll_reactor.ipp
+++ b/asio/include/asio/detail/impl/epoll_reactor.ipp
@@ -168,7 +168,18 @@
ev.data.ptr = descriptor_data;
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
+ {
+ if (errno == EPERM)
+ {
+ // This file descriptor type is not supported by epoll. However, if it is
+ // a regular file then operations on it will not block. We will allow
+ // this descriptor to be used and fail later if an operation on it would
+ // otherwise require a trip through the reactor.
+ descriptor_data->registered_events_ = 0;
+ return 0;
+ }
return errno;
+ }
return 0;
}
@@ -243,6 +254,13 @@
return;
}
+ if (descriptor_data->registered_events_ == 0)
+ {
+ op->ec_ = asio::error::operation_not_supported;
+ scheduler_.post_immediate_completion(op, is_continuation);
+ return;
+ }
+
if (op_type == write_op)
{
if ((descriptor_data->registered_events_ & EPOLLOUT) == 0)
@@ -264,6 +282,12 @@
}
}
}
+ else if (descriptor_data->registered_events_ == 0)
+ {
+ op->ec_ = asio::error::operation_not_supported;
+ scheduler_.post_immediate_completion(op, is_continuation);
+ return;
+ }
else
{
if (op_type == write_op)
@@ -321,7 +345,7 @@
// The descriptor will be automatically removed from the epoll set when
// it is closed.
}
- else
+ else if (descriptor_data->registered_events_ != 0)
{
epoll_event ev = { 0, { 0 } };
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
diff --git a/asio/src/doc/overview/posix.qbk b/asio/src/doc/overview/posix.qbk
index e35e72e..19c9178 100644
--- a/asio/src/doc/overview/posix.qbk
+++ b/asio/src/doc/overview/posix.qbk
@@ -75,7 +75,15 @@
Asio includes classes added to permit synchronous and asynchronous read and
write operations to be performed on POSIX file descriptors, such as pipes,
-standard input and output, and various devices (but /not/ regular files).
+standard input and output, and various devices.
+
+These classes also provide limited support for regular files. This support
+assumes that the underlying read and write operations provided by the operating
+system never fail with `EAGAIN` or `EWOULDBLOCK`. (This assumption normally
+holds for buffered file I/O.) Synchronous and asynchronous read and write
+operations on file descriptors will succeed but the I/O will always be
+performed immediately. Wait operations, and operations involving
+`asio::null_buffers`, are not portably supported.
For example, to perform read and write operations on standard input
and output, the following objects may be created: