|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r58628 - trunk/boost/asio/detail
From: chris_at_[hidden]
Date: 2010-01-02 04:48:03
Author: chris_kohlhoff
Date: 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
New Revision: 58628
URL: http://svn.boost.org/trac/boost/changeset/58628
Log:
Don't block signals while performing system calls, but instead restart the
calls if they are interrupted.
Text files modified:
trunk/boost/asio/detail/dev_poll_reactor.hpp | 3
trunk/boost/asio/detail/epoll_reactor.hpp | 3
trunk/boost/asio/detail/eventfd_select_interrupter.hpp | 39 +++++---
trunk/boost/asio/detail/kqueue_reactor.hpp | 3
trunk/boost/asio/detail/pipe_select_interrupter.hpp | 17 ++-
trunk/boost/asio/detail/reactive_descriptor_service.hpp | 52 +++++++----
trunk/boost/asio/detail/reactive_socket_service.hpp | 181 +++++++++++++++++++++++----------------
trunk/boost/asio/detail/select_reactor.hpp | 3
8 files changed, 177 insertions(+), 124 deletions(-)
Modified: trunk/boost/asio/detail/dev_poll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/dev_poll_reactor.hpp (original)
+++ trunk/boost/asio/detail/dev_poll_reactor.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -402,9 +402,6 @@
lock.lock();
wait_in_progress_ = false;
- // Block signals while performing operations.
- boost::asio::detail::signal_blocker sb;
-
// Dispatch the waiting events.
for (int i = 0; i < num_events; ++i)
{
Modified: trunk/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor.hpp (original)
+++ trunk/boost/asio/detail/epoll_reactor.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -472,9 +472,6 @@
lock.lock();
wait_in_progress_ = false;
- // Block signals while performing operations.
- boost::asio::detail::signal_blocker sb;
-
// Dispatch the waiting events.
for (int i = 0; i < num_events; ++i)
{
Modified: trunk/boost/asio/detail/eventfd_select_interrupter.hpp
==============================================================================
--- trunk/boost/asio/detail/eventfd_select_interrupter.hpp (original)
+++ trunk/boost/asio/detail/eventfd_select_interrupter.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -24,14 +24,14 @@
#include <boost/system/system_error.hpp>
#include <boost/asio/detail/pop_options.hpp>
-#if defined(linux)
+#if defined(__linux__)
# if !defined(BOOST_ASIO_DISABLE_EVENTFD)
# include <linux/version.h>
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
# define BOOST_ASIO_HAS_EVENTFD
# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD)
-#endif // defined(linux)
+#endif // defined(__linux__)
#if defined(BOOST_ASIO_HAS_EVENTFD)
@@ -108,21 +108,32 @@
{
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;
+ for (;;)
+ {
+ // Only perform one read. The kernel maintains an atomic counter.
+ uint64_t counter(0);
+ errno = 0;
+ int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t));
+ if (bytes_read < 0 && errno == EINTR)
+ continue;
+ 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;
+ for (;;)
+ {
+ // Clear all data from the pipe.
+ char data[1024];
+ int bytes_read = ::read(read_descriptor_, data, sizeof(data));
+ if (bytes_read < 0 && errno == EINTR)
+ continue;
+ bool was_interrupted = (bytes_read > 0);
+ while (bytes_read == sizeof(data))
+ bytes_read = ::read(read_descriptor_, data, sizeof(data));
+ return was_interrupted;
+ }
}
}
Modified: trunk/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/kqueue_reactor.hpp (original)
+++ trunk/boost/asio/detail/kqueue_reactor.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -442,9 +442,6 @@
lock.lock();
wait_in_progress_ = false;
- // Block signals while performing operations.
- boost::asio::detail::signal_blocker sb;
-
// Dispatch the waiting events.
for (int i = 0; i < num_events; ++i)
{
Modified: trunk/boost/asio/detail/pipe_select_interrupter.hpp
==============================================================================
--- trunk/boost/asio/detail/pipe_select_interrupter.hpp (original)
+++ trunk/boost/asio/detail/pipe_select_interrupter.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -79,12 +79,17 @@
// Reset the select interrupt. Returns true if the call was interrupted.
bool reset()
{
- 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;
+ for (;;)
+ {
+ char data[1024];
+ int bytes_read = ::read(read_descriptor_, data, sizeof(data));
+ if (bytes_read < 0 && errno == EINTR)
+ continue;
+ 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.
Modified: trunk/boost/asio/detail/reactive_descriptor_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_descriptor_service.hpp (original)
+++ trunk/boost/asio/detail/reactive_descriptor_service.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -348,16 +348,23 @@
boost::asio::buffer_size(buffer));
}
- // Write the data.
- int bytes = descriptor_ops::gather_write(descriptor_, bufs, i, ec);
+ for (;;)
+ {
+ // Write the data.
+ int bytes = descriptor_ops::gather_write(descriptor_, bufs, i, ec);
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
- bytes_transferred = (bytes < 0 ? 0 : bytes);
- return true;
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
+ return true;
+ }
}
void complete(const boost::system::error_code& ec,
@@ -600,18 +607,25 @@
boost::asio::buffer_size(buffer));
}
- // Read some data.
- int bytes = descriptor_ops::scatter_read(descriptor_, bufs, i, ec);
- if (bytes == 0)
- ec = boost::asio::error::eof;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
+ for (;;)
+ {
+ // Read some data.
+ int bytes = descriptor_ops::scatter_read(descriptor_, bufs, i, ec);
+ if (bytes == 0)
+ ec = boost::asio::error::eof;
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
- bytes_transferred = (bytes < 0 ? 0 : bytes);
- return true;
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
+ return true;
+ }
}
void complete(const boost::system::error_code& ec,
Modified: trunk/boost/asio/detail/reactive_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_socket_service.hpp (original)
+++ trunk/boost/asio/detail/reactive_socket_service.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -644,16 +644,23 @@
boost::asio::buffer_size(buffer));
}
- // Send the data.
- int bytes = socket_ops::send(socket_, bufs, i, flags_, ec);
+ for (;;)
+ {
+ // Send the data.
+ int bytes = socket_ops::send(socket_, bufs, i, flags_, ec);
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
- bytes_transferred = (bytes < 0 ? 0 : bytes);
- return true;
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
+ return true;
+ }
}
void complete(const boost::system::error_code& ec,
@@ -881,17 +888,24 @@
boost::asio::buffer_size(buffer));
}
- // Send the data.
- int bytes = socket_ops::sendto(socket_, bufs, i, flags_,
- destination_.data(), destination_.size(), ec);
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
+ for (;;)
+ {
+ // Send the data.
+ int bytes = socket_ops::sendto(socket_, bufs, i, flags_,
+ destination_.data(), destination_.size(), ec);
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
- bytes_transferred = (bytes < 0 ? 0 : bytes);
- return true;
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
+ return true;
+ }
}
void complete(const boost::system::error_code& ec,
@@ -1086,18 +1100,25 @@
boost::asio::buffer_size(buffer));
}
- // Receive some data.
- int bytes = socket_ops::recv(socket_, bufs, i, flags_, ec);
- if (bytes == 0 && protocol_type_ == SOCK_STREAM)
- ec = boost::asio::error::eof;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
+ for (;;)
+ {
+ // Receive some data.
+ int bytes = socket_ops::recv(socket_, bufs, i, flags_, ec);
+ if (bytes == 0 && protocol_type_ == SOCK_STREAM)
+ ec = boost::asio::error::eof;
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
- bytes_transferred = (bytes < 0 ? 0 : bytes);
- return true;
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
+ return true;
+ }
}
void complete(const boost::system::error_code& ec,
@@ -1331,21 +1352,28 @@
boost::asio::buffer_size(buffer));
}
- // Receive some data.
- std::size_t addr_len = sender_endpoint_.capacity();
- int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_,
- sender_endpoint_.data(), &addr_len, ec);
- if (bytes == 0 && protocol_type_ == SOCK_STREAM)
- ec = boost::asio::error::eof;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
+ for (;;)
+ {
+ // Receive some data.
+ std::size_t addr_len = sender_endpoint_.capacity();
+ int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_,
+ sender_endpoint_.data(), &addr_len, ec);
+ if (bytes == 0 && protocol_type_ == SOCK_STREAM)
+ ec = boost::asio::error::eof;
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
- sender_endpoint_.resize(addr_len);
- bytes_transferred = (bytes < 0 ? 0 : bytes);
- return true;
+ sender_endpoint_.resize(addr_len);
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
+ return true;
+ }
}
void complete(const boost::system::error_code& ec,
@@ -1535,43 +1563,50 @@
if (ec)
return true;
- // Accept the waiting connection.
- socket_holder new_socket;
- std::size_t addr_len = 0;
- if (peer_endpoint_)
+ for (;;)
{
- addr_len = peer_endpoint_->capacity();
- new_socket.reset(socket_ops::accept(socket_,
- peer_endpoint_->data(), &addr_len, ec));
- }
- else
- {
- new_socket.reset(socket_ops::accept(socket_, 0, 0, ec));
- }
+ // Accept the waiting connection.
+ socket_holder new_socket;
+ std::size_t addr_len = 0;
+ if (peer_endpoint_)
+ {
+ addr_len = peer_endpoint_->capacity();
+ new_socket.reset(socket_ops::accept(socket_,
+ peer_endpoint_->data(), &addr_len, ec));
+ }
+ else
+ {
+ new_socket.reset(socket_ops::accept(socket_, 0, 0, ec));
+ }
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
- if (ec == boost::asio::error::connection_aborted
- && !enable_connection_aborted_)
- return false;
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+ if (ec == boost::asio::error::connection_aborted
+ && !enable_connection_aborted_)
+ return false;
#if defined(EPROTO)
- if (ec.value() == EPROTO && !enable_connection_aborted_)
- return false;
+ if (ec.value() == EPROTO && !enable_connection_aborted_)
+ return false;
#endif // defined(EPROTO)
- // Transfer ownership of the new socket to the peer object.
- if (!ec)
- {
- if (peer_endpoint_)
- peer_endpoint_->resize(addr_len);
- peer_.assign(protocol_, new_socket.get(), ec);
+ // Transfer ownership of the new socket to the peer object.
if (!ec)
- new_socket.release();
- }
+ {
+ if (peer_endpoint_)
+ peer_endpoint_->resize(addr_len);
+ peer_.assign(protocol_, new_socket.get(), ec);
+ if (!ec)
+ new_socket.release();
+ }
- return true;
+ return true;
+ }
}
void complete(const boost::system::error_code& ec, std::size_t)
Modified: trunk/boost/asio/detail/select_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/select_reactor.hpp (original)
+++ trunk/boost/asio/detail/select_reactor.hpp 2010-01-02 04:48:01 EST (Sat, 02 Jan 2010)
@@ -369,9 +369,6 @@
lock.lock();
select_in_progress_ = false;
- // Block signals while dispatching operations.
- boost::asio::detail::signal_blocker sb;
-
// Reset the interrupter.
if (retval > 0 && read_fds.is_set(interrupter_.read_descriptor()))
interrupter_.reset();
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk