mirror of
https://github.com/boostorg/asio.git
synced 2026-01-27 06:32:08 +00:00
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.
This commit is contained in:
@@ -75,7 +75,15 @@ target operating system. A program may test for the macro
|
||||
|
||||
Boost.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
|
||||
`boost::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:
|
||||
|
||||
@@ -164,7 +164,18 @@ int epoll_reactor::register_descriptor(socket_type descriptor,
|
||||
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;
|
||||
}
|
||||
@@ -235,6 +246,13 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
return;
|
||||
}
|
||||
|
||||
if (descriptor_data->registered_events_ == 0)
|
||||
{
|
||||
op->ec_ = boost::asio::error::operation_not_supported;
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (op_type == write_op)
|
||||
{
|
||||
if ((descriptor_data->registered_events_ & EPOLLOUT) == 0)
|
||||
@@ -256,6 +274,12 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (descriptor_data->registered_events_ == 0)
|
||||
{
|
||||
op->ec_ = boost::asio::error::operation_not_supported;
|
||||
io_service_.post_immediate_completion(op, is_continuation);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (op_type == write_op)
|
||||
@@ -313,7 +337,7 @@ void epoll_reactor::deregister_descriptor(socket_type descriptor,
|
||||
// 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);
|
||||
|
||||
Reference in New Issue
Block a user