sync asio

This commit is contained in:
Marcos Pinto 2007-10-29 03:10:12 +00:00
parent 9b59c0507e
commit c059d5162b
29 changed files with 308 additions and 148 deletions

View File

@ -732,7 +732,7 @@ public:
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @code void handler(
* const asio::system_error& error, // Result of operation.
* const asio::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or

View File

@ -34,7 +34,8 @@ public:
/// The underlying implementation type of I/O object.
typedef typename service_type::implementation_type implementation_type;
/// Get the io_service associated with the object.
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
/**
* This function may be used to obtain the io_service object that the I/O
* object uses to dispatch handlers for asynchronous operations.
@ -44,7 +45,20 @@ public:
*/
asio::io_service& io_service()
{
return service.io_service();
return service.get_io_service();
}
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_service& get_io_service()
{
return service.get_io_service();
}
protected:

View File

@ -564,7 +564,8 @@ public:
if (this->service.open(this->implementation,
peer_endpoint.protocol(), ec))
{
this->io_service().post(asio::detail::bind_handler(handler, ec));
this->get_io_service().post(
asio::detail::bind_handler(handler, ec));
return;
}
}

View File

@ -93,10 +93,17 @@ public:
return next_layer_.lowest_layer();
}
/// Get the io_service associated with the object.
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
asio::io_service& io_service()
{
return next_layer_.io_service();
return next_layer_.get_io_service();
}
/// Get the io_service associated with the object.
asio::io_service& get_io_service()
{
return next_layer_.get_io_service();
}
/// Close the stream.
@ -207,7 +214,7 @@ public:
buffer(
storage_.data() + previous_size,
storage_.size() - previous_size),
fill_handler<ReadHandler>(io_service(),
fill_handler<ReadHandler>(get_io_service(),
storage_, previous_size, handler));
}
@ -295,12 +302,12 @@ public:
if (storage_.empty())
{
async_fill(read_some_handler<MutableBufferSequence, ReadHandler>(
io_service(), storage_, buffers, handler));
get_io_service(), storage_, buffers, handler));
}
else
{
std::size_t length = copy(buffers);
io_service().post(detail::bind_handler(
get_io_service().post(detail::bind_handler(
handler, asio::error_code(), length));
}
}

View File

@ -83,10 +83,17 @@ public:
return stream_impl_.lowest_layer();
}
/// Get the io_service associated with the object.
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
asio::io_service& io_service()
{
return stream_impl_.io_service();
return stream_impl_.get_io_service();
}
/// Get the io_service associated with the object.
asio::io_service& get_io_service()
{
return stream_impl_.get_io_service();
}
/// Close the stream.

View File

@ -94,10 +94,17 @@ public:
return next_layer_.lowest_layer();
}
/// Get the io_service associated with the object.
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
asio::io_service& io_service()
{
return next_layer_.io_service();
return next_layer_.get_io_service();
}
/// Get the io_service associated with the object.
asio::io_service& get_io_service()
{
return next_layer_.get_io_service();
}
/// Close the stream.
@ -165,7 +172,7 @@ public:
void async_flush(WriteHandler handler)
{
async_write(next_layer_, buffer(storage_.data(), storage_.size()),
flush_handler<WriteHandler>(io_service(), storage_, handler));
flush_handler<WriteHandler>(get_io_service(), storage_, handler));
}
/// Write the given data to the stream. Returns the number of bytes written.
@ -253,12 +260,12 @@ public:
if (storage_.size() == storage_.capacity())
{
async_flush(write_some_handler<ConstBufferSequence, WriteHandler>(
io_service(), storage_, buffers, handler));
get_io_service(), storage_, buffers, handler));
}
else
{
std::size_t bytes_copied = copy(buffers);
io_service().post(detail::bind_handler(
get_io_service().post(detail::bind_handler(
handler, asio::error_code(), bytes_copied));
}
}

View File

@ -180,7 +180,7 @@ public:
{
impl.might_have_pending_waits = true;
scheduler_.schedule_timer(timer_queue_, impl.expiry,
wait_handler<Handler>(this->io_service(), handler), &impl);
wait_handler<Handler>(this->get_io_service(), handler), &impl);
}
private:

View File

@ -19,6 +19,7 @@
#include "asio/detail/push_options.hpp"
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include "asio/detail/pop_options.hpp"
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
@ -27,6 +28,8 @@
#include <fcntl.h>
#include "asio/detail/pop_options.hpp"
#include "asio/error.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/socket_types.hpp"
namespace asio {
@ -46,6 +49,12 @@ public:
write_descriptor_ = pipe_fds[1];
::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
}
else
{
asio::error_code ec(errno, asio::error::system_category);
asio::system_error e(ec, "pipe_select_interrupter");
boost::throw_exception(e);
}
}
// Destructor.

View File

@ -58,7 +58,7 @@ public:
}
private:
fd_set fd_set_;
mutable fd_set fd_set_;
socket_type max_descriptor_;
};

View File

@ -624,7 +624,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@ -645,7 +645,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (total_buffer_size == 0)
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error_code(), 0));
return;
}
@ -658,7 +658,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->io_service().post(bind_handler(handler, ec, 0));
this->get_io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@ -666,7 +666,7 @@ public:
reactor_.start_write_op(impl.socket_,
send_handler<ConstBufferSequence, Handler>(
impl.socket_, this->io_service(), buffers, flags, handler));
impl.socket_, this->get_io_service(), buffers, flags, handler));
}
}
@ -804,7 +804,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@ -816,7 +816,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->io_service().post(bind_handler(handler, ec, 0));
this->get_io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@ -824,7 +824,7 @@ public:
reactor_.start_write_op(impl.socket_,
send_to_handler<ConstBufferSequence, Handler>(
impl.socket_, this->io_service(), buffers,
impl.socket_, this->get_io_service(), buffers,
destination, flags, handler));
}
}
@ -975,7 +975,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@ -996,7 +996,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (total_buffer_size == 0)
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error_code(), 0));
return;
}
@ -1009,7 +1009,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->io_service().post(bind_handler(handler, ec, 0));
this->get_io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@ -1019,13 +1019,13 @@ public:
{
reactor_.start_except_op(impl.socket_,
receive_handler<MutableBufferSequence, Handler>(
impl.socket_, this->io_service(), buffers, flags, handler));
impl.socket_, this->get_io_service(), buffers, flags, handler));
}
else
{
reactor_.start_read_op(impl.socket_,
receive_handler<MutableBufferSequence, Handler>(
impl.socket_, this->io_service(), buffers, flags, handler));
impl.socket_, this->get_io_service(), buffers, flags, handler));
}
}
}
@ -1181,7 +1181,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
}
else
@ -1193,7 +1193,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->io_service().post(bind_handler(handler, ec, 0));
this->get_io_service().post(bind_handler(handler, ec, 0));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@ -1201,7 +1201,7 @@ public:
reactor_.start_read_op(impl.socket_,
receive_from_handler<MutableBufferSequence, Handler>(
impl.socket_, this->io_service(), buffers,
impl.socket_, this->get_io_service(), buffers,
sender_endpoint, flags, handler));
}
}
@ -1384,12 +1384,12 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
}
else if (peer.is_open())
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::already_open));
}
else
@ -1401,7 +1401,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->io_service().post(bind_handler(handler, ec));
this->get_io_service().post(bind_handler(handler, ec));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@ -1409,7 +1409,7 @@ public:
reactor_.start_read_op(impl.socket_,
accept_handler<Socket, Handler>(
impl.socket_, this->io_service(),
impl.socket_, this->get_io_service(),
peer, impl.protocol_, peer_endpoint,
(impl.flags_ & implementation_type::enable_connection_aborted) != 0,
handler));
@ -1515,7 +1515,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
return;
}
@ -1527,7 +1527,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->io_service().post(bind_handler(handler, ec));
this->get_io_service().post(bind_handler(handler, ec));
return;
}
impl.flags_ |= implementation_type::internal_non_blocking;
@ -1541,7 +1541,7 @@ public:
{
// The connect operation has finished successfully so we need to post the
// handler immediately.
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error_code()));
}
else if (ec == asio::error::in_progress
@ -1551,13 +1551,13 @@ public:
// until the socket becomes writeable.
boost::shared_ptr<bool> completed(new bool(false));
reactor_.start_write_and_except_ops(impl.socket_,
connect_handler<Handler>(
impl.socket_, completed, this->io_service(), reactor_, handler));
connect_handler<Handler>(impl.socket_, completed,
this->get_io_service(), reactor_, handler));
}
else
{
// The connect operation has failed, so post the handler immediately.
this->io_service().post(bind_handler(handler, ec));
this->get_io_service().post(bind_handler(handler, ec));
}
}

View File

@ -213,7 +213,7 @@ public:
start_work_thread();
work_io_service_->post(
resolve_query_handler<Handler>(
impl, query, this->io_service(), handler));
impl, query, this->get_io_service(), handler));
}
}
@ -309,7 +309,7 @@ public:
start_work_thread();
work_io_service_->post(
resolve_endpoint_handler<Handler>(
impl, endpoint, this->io_service(), handler));
impl, endpoint, this->get_io_service(), handler));
}
}

View File

@ -39,6 +39,13 @@ namespace socket_ops {
struct msghdr { int msg_namelen; };
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#if defined(__hpux)
// HP-UX doesn't declare these functions extern "C", so they are declared again
// here to avoid linker errors about undefined symbols.
extern "C" char* if_indextoname(unsigned int, char*);
extern "C" unsigned int if_nametoindex(const char*);
#endif // defined(__hpux)
inline void clear_error(asio::error_code& ec)
{
errno = 0;
@ -542,10 +549,12 @@ inline int select(int nfds, fd_set* readfds, fd_set* writefds,
timeout->tv_usec = 1000;
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
#if defined(__hpux) && defined(__HP_aCC) && !defined(_XOPEN_SOURCE_EXTENDED)
return error_wrapper(::select(nfds,
reinterpret_cast<int*>(readfds), reinterpret_cast<int*>(writefds),
reinterpret_cast<int*>(exceptfds), timeout), ec);
#if defined(__hpux) && defined(__HP_aCC)
timespec ts;
ts.tv_sec = timeout ? timeout->tv_sec : 0;
ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
return error_wrapper(::pselect(nfds, readfds,
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
#else
return error_wrapper(::select(nfds, readfds,
writefds, exceptfds, timeout), ec);

View File

@ -29,12 +29,12 @@
# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER) || defined(__BORLANDC__)
# pragma message("Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately")
# pragma message("Assuming _WIN32_WINNT=0x0500 (i.e. Windows 2000 target)")
# pragma message("Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target)")
# else // defined(_MSC_VER) || defined(__BORLANDC__)
# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately
# warning Assuming _WIN32_WINNT=0x0500 (i.e. Windows 2000 target)
# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target)
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
# define _WIN32_WINNT 0x0500
# define _WIN32_WINNT 0x0501
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER)
# if defined(_WIN32) && !defined(WIN32)

View File

@ -276,7 +276,7 @@ public:
if (impl_->first_waiter_ == 0)
impl_->last_waiter_ = 0;
lock.unlock();
service_impl_.io_service().post(
service_impl_.get_io_service().post(
invoke_current_handler(service_impl_, impl_));
}
}
@ -429,7 +429,7 @@ public:
// This handler now has the lock, so can be dispatched immediately.
impl->current_handler_ = ptr.get();
lock.unlock();
this->io_service().dispatch(invoke_current_handler(*this, impl));
this->get_io_service().dispatch(invoke_current_handler(*this, impl));
ptr.release();
}
else
@ -469,7 +469,7 @@ public:
// This handler now has the lock, so can be dispatched immediately.
impl->current_handler_ = ptr.get();
lock.unlock();
this->io_service().post(invoke_current_handler(*this, impl));
this->get_io_service().post(invoke_current_handler(*this, impl));
ptr.release();
}
else

View File

@ -225,16 +225,18 @@ private:
{
bool more_handlers = (!handler_queue_.empty());
task_interrupted_ = more_handlers || polling;
lock.unlock();
// If the task has already run and we're polling then we're done.
if (task_has_run && polling)
{
task_interrupted_ = true;
handler_queue_.push(&task_handler_);
ec = asio::error_code();
return 0;
}
task_has_run = true;
lock.unlock();
task_cleanup c(lock, *this);
// Run the task. May throw an exception. Only block if the handler
@ -316,6 +318,8 @@ private:
}
// Helper class to perform task-related operations on block exit.
class task_cleanup;
friend class task_cleanup;
class task_cleanup
{
public:

View File

@ -327,7 +327,7 @@ public:
ec = asio::error::bad_descriptor;
}
else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
::GetModuleHandle("KERNEL32"), "CancelIoEx"))
::GetModuleHandleA("KERNEL32"), "CancelIoEx"))
{
// The version of Windows supports cancellation from any thread.
typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
@ -767,7 +767,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@ -783,7 +783,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->io_service(), impl.cancel_token_, buffers, handler);
this->get_io_service(), impl.cancel_token_, buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@ -803,7 +803,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
{
asio::io_service::work work(this->io_service());
asio::io_service::work work(this->get_io_service());
ptr.reset();
asio::error_code error;
iocp_service_.post(bind_handler(handler, error, 0));
@ -819,7 +819,7 @@ public:
// Check if the operation completed immediately.
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->io_service());
asio::io_service::work work(this->get_io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
@ -958,7 +958,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@ -974,7 +974,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->io_service(), buffers, handler);
this->get_io_service(), buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@ -998,7 +998,7 @@ public:
// Check if the operation completed immediately.
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->io_service());
asio::io_service::work work(this->get_io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
@ -1170,7 +1170,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@ -1186,7 +1186,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->io_service(), impl.cancel_token_, buffers, handler);
this->get_io_service(), impl.cancel_token_, buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@ -1205,7 +1205,7 @@ public:
// A request to receive 0 bytes on a stream socket is a no-op.
if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
{
asio::io_service::work work(this->io_service());
asio::io_service::work work(this->get_io_service());
ptr.reset();
asio::error_code error;
iocp_service_.post(bind_handler(handler, error, 0));
@ -1220,7 +1220,7 @@ public:
DWORD last_error = ::WSAGetLastError();
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->io_service());
asio::io_service::work work(this->get_io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
@ -1390,7 +1390,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor, 0));
return;
}
@ -1406,7 +1406,7 @@ public:
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
raw_handler_ptr<alloc_traits> raw_ptr(handler);
handler_ptr<alloc_traits> ptr(raw_ptr,
this->io_service(), sender_endp, buffers, handler);
this->get_io_service(), sender_endp, buffers, handler);
// Copy buffers into WSABUF array.
::WSABUF bufs[max_buffers];
@ -1429,7 +1429,7 @@ public:
DWORD last_error = ::WSAGetLastError();
if (result != 0 && last_error != WSA_IO_PENDING)
{
asio::io_service::work work(this->io_service());
asio::io_service::work work(this->get_io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
@ -1517,7 +1517,7 @@ public:
peer_(peer),
protocol_(protocol),
peer_endpoint_(peer_endpoint),
work_(io_service.io_service()),
work_(io_service.get_io_service()),
enable_connection_aborted_(enable_connection_aborted),
handler_(handler)
{
@ -1706,7 +1706,7 @@ public:
// Check whether acceptor has been initialised.
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
return;
}
@ -1714,7 +1714,7 @@ public:
// Check that peer socket has not already been opened.
if (peer.is_open())
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::already_open));
return;
}
@ -1731,7 +1731,7 @@ public:
impl.protocol_.type(), impl.protocol_.protocol(), ec));
if (sock.get() == invalid_socket)
{
this->io_service().post(bind_handler(handler, ec));
this->get_io_service().post(bind_handler(handler, ec));
return;
}
@ -1769,7 +1769,7 @@ public:
}
else
{
asio::io_service::work work(this->io_service());
asio::io_service::work work(this->get_io_service());
ptr.reset();
asio::error_code ec(last_error,
asio::error::system_category);
@ -1888,7 +1888,7 @@ public:
{
if (!is_open(impl))
{
this->io_service().post(bind_handler(handler,
this->get_io_service().post(bind_handler(handler,
asio::error::bad_descriptor));
return;
}
@ -1905,7 +1905,8 @@ public:
reinterpret_cast<void**>(&reactor_), 0, 0));
if (!reactor)
{
reactor = &(asio::use_service<reactor_type>(this->io_service()));
reactor = &(asio::use_service<reactor_type>(
this->get_io_service()));
interlocked_exchange_pointer(
reinterpret_cast<void**>(&reactor_), reactor);
}
@ -1916,7 +1917,7 @@ public:
asio::error_code ec;
if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
{
this->io_service().post(bind_handler(handler, ec));
this->get_io_service().post(bind_handler(handler, ec));
return;
}
@ -1933,7 +1934,7 @@ public:
// The connect operation has finished successfully so we need to post the
// handler immediately.
this->io_service().post(bind_handler(handler, ec));
this->get_io_service().post(bind_handler(handler, ec));
}
else if (ec == asio::error::in_progress
|| ec == asio::error::would_block)
@ -1945,7 +1946,7 @@ public:
connect_handler<Handler>(
impl.socket_,
(impl.flags_ & implementation_type::user_set_non_blocking) != 0,
completed, this->io_service(), *reactor, handler));
completed, this->get_io_service(), *reactor, handler));
}
else
{
@ -1958,7 +1959,7 @@ public:
}
// The connect operation has failed, so post the handler immediately.
this->io_service().post(bind_handler(handler, ec));
this->get_io_service().post(bind_handler(handler, ec));
}
}

View File

@ -61,7 +61,7 @@ enum basic_errors
/// Address family not supported by protocol.
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
/// Address already in use.
/// Port already in use.
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
/// Transport endpoint is already connected.
@ -82,7 +82,7 @@ enum basic_errors
/// Bad file descriptor.
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
/// Bad address.
/// Bad port.
fault = ASIO_SOCKET_ERROR(EFAULT),
/// No route to host.
@ -197,6 +197,10 @@ enum misc_errors
not_found
};
enum ssl_errors
{
};
// boostify: error category definitions go here.
inline asio::error_code make_error_code(basic_errors e)
@ -219,6 +223,11 @@ inline asio::error_code make_error_code(misc_errors e)
return asio::error_code(static_cast<int>(e), misc_category);
}
inline asio::error_code make_error_code(ssl_errors e)
{
return asio::error_code(static_cast<int>(e), ssl_category);
}
} // namespace error
} // namespace asio

View File

@ -84,7 +84,7 @@ inline std::string error_code::message() const
return strerror(value_);
#elif defined(__MACH__) && defined(__APPLE__) \
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
|| defined(_AIX)
|| defined(_AIX) || defined(__hpux) || defined(__osf__)
char buf[256] = "";
strerror_r(value_, buf, sizeof(buf));
return buf;

View File

@ -158,6 +158,11 @@ inline asio::io_service& io_service::work::io_service()
return io_service_;
}
inline asio::io_service& io_service::work::get_io_service()
{
return io_service_;
}
inline io_service::service::service(asio::io_service& owner)
: owner_(owner),
type_info_(0),
@ -174,6 +179,11 @@ inline asio::io_service& io_service::service::io_service()
return owner_;
}
inline asio::io_service& io_service::service::get_io_service()
{
return owner_;
}
template <typename Service>
inline Service& use_service(io_service& ios)
{

View File

@ -19,6 +19,7 @@
#include "asio/detail/push_options.hpp"
#include <algorithm>
#include <boost/optional.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/buffer.hpp"
@ -138,23 +139,25 @@ namespace detail
std::size_t bytes_transferred)
{
total_transferred_ += bytes_transferred;
buffers_.consume(bytes_transferred);
if (completion_condition_(ec, total_transferred_)
|| buffers_.begin() == buffers_.end())
buffers_->consume(bytes_transferred);
if ((*completion_condition_)(ec, total_transferred_)
|| buffers_->begin() == buffers_->end())
{
buffers_.reset();
completion_condition_.reset();
handler_(ec, total_transferred_);
}
else
{
stream_.async_read_some(buffers_, *this);
stream_.async_read_some(*buffers_, *this);
}
}
//private:
AsyncReadStream& stream_;
buffers_type buffers_;
boost::optional<buffers_type> buffers_;
std::size_t total_transferred_;
CompletionCondition completion_condition_;
boost::optional<CompletionCondition> completion_condition_;
ReadHandler handler_;
};
@ -235,8 +238,9 @@ namespace detail
total_transferred_ += bytes_transferred;
streambuf_.commit(bytes_transferred);
if (streambuf_.size() == streambuf_.max_size()
|| completion_condition_(ec, total_transferred_))
|| (*completion_condition_)(ec, total_transferred_))
{
completion_condition_.reset();
handler_(ec, total_transferred_);
}
else
@ -251,7 +255,7 @@ namespace detail
AsyncReadStream& stream_;
asio::basic_streambuf<Allocator>& streambuf_;
std::size_t total_transferred_;
CompletionCondition completion_condition_;
boost::optional<CompletionCondition> completion_condition_;
ReadHandler handler_;
};

View File

@ -17,6 +17,10 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <boost/optional.hpp>
#include "asio/detail/pop_options.hpp"
#include "asio/buffer.hpp"
#include "asio/completion_condition.hpp"
#include "asio/detail/bind_handler.hpp"
@ -124,23 +128,25 @@ namespace detail
std::size_t bytes_transferred)
{
total_transferred_ += bytes_transferred;
buffers_.consume(bytes_transferred);
if (completion_condition_(ec, total_transferred_)
|| buffers_.begin() == buffers_.end())
buffers_->consume(bytes_transferred);
if ((*completion_condition_)(ec, total_transferred_)
|| buffers_->begin() == buffers_->end())
{
buffers_.reset();
completion_condition_.reset();
handler_(ec, total_transferred_);
}
else
{
stream_.async_write_some(buffers_, *this);
stream_.async_write_some(*buffers_, *this);
}
}
//private:
AsyncWriteStream& stream_;
buffers_type buffers_;
boost::optional<buffers_type> buffers_;
std::size_t total_transferred_;
CompletionCondition completion_condition_;
boost::optional<CompletionCondition> completion_condition_;
WriteHandler handler_;
};

View File

@ -381,7 +381,8 @@ public:
private:
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
detail::winsock_init<> init_;
#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX)
#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \
|| defined(__osf__)
detail::signal_init<> init_;
#endif
@ -429,9 +430,13 @@ public:
*/
~work();
/// Get the io_service associated with the work.
/// (Deprecated: use get_io_service().) Get the io_service associated with the
/// work.
asio::io_service& io_service();
/// Get the io_service associated with the work.
asio::io_service& get_io_service();
private:
// Prevent assignment.
void operator=(const work& other);
@ -454,9 +459,13 @@ class io_service::service
: private noncopyable
{
public:
/// Get the io_service object that owns the service.
/// (Deprecated: use get_io_service().) Get the io_service object that owns
/// the service.
asio::io_service& io_service();
/// Get the io_service object that owns the service.
asio::io_service& get_io_service();
protected:
/// Constructor.
/**

View File

@ -300,7 +300,7 @@ public:
{
using namespace std; // For memcmp.
int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
sizeof(asio::detail::in6_addr_type)) < 0;
sizeof(asio::detail::in6_addr_type));
if (memcmp_result < 0)
return true;
if (memcmp_result > 0)

View File

@ -32,52 +32,60 @@ namespace ip {
namespace detail {
namespace socket_option {
// Helper template for implementing boolean-based options.
// Helper template for implementing multicast enable loopback options.
template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name>
class boolean
class multicast_enable_loopback
{
public:
#if defined(__sun) || defined(_AIX) || defined(__osf__)
typedef unsigned char value_type;
#if defined(__sun) || defined(__osf__)
typedef unsigned char ipv4_value_type;
typedef unsigned char ipv6_value_type;
#elif defined(_AIX) || defined(__hpux)
typedef unsigned char ipv4_value_type;
typedef unsigned int ipv6_value_type;
#else
typedef int value_type;
typedef int ipv4_value_type;
typedef int ipv6_value_type;
#endif
// Default constructor.
boolean()
: value_(0)
multicast_enable_loopback()
: ipv4_value_(0),
ipv6_value_(0)
{
}
// Construct with a specific option value.
explicit boolean(bool v)
: value_(v ? 1 : 0)
explicit multicast_enable_loopback(bool v)
: ipv4_value_(v ? 1 : 0),
ipv6_value_(v ? 1 : 0)
{
}
// Set the value of the boolean.
boolean& operator=(bool v)
multicast_enable_loopback& operator=(bool v)
{
value_ = v ? 1 : 0;
ipv4_value_ = v ? 1 : 0;
ipv6_value_ = v ? 1 : 0;
return *this;
}
// Get the current value of the boolean.
bool value() const
{
return !!value_;
return !!ipv4_value_;
}
// Convert to bool.
operator bool() const
{
return !!value_;
return !!ipv4_value_;
}
// Test for false.
bool operator!() const
{
return !value_;
return !ipv4_value_;
}
// Get the level of the socket option.
@ -100,35 +108,58 @@ public:
// Get the address of the boolean data.
template <typename Protocol>
value_type* data(const Protocol&)
void* data(const Protocol& protocol)
{
return &value_;
if (protocol.family() == PF_INET6)
return &ipv6_value_;
return &ipv4_value_;
}
// Get the address of the boolean data.
template <typename Protocol>
const value_type* data(const Protocol&) const
const void* data(const Protocol& protocol) const
{
return &value_;
if (protocol.family() == PF_INET6)
return &ipv6_value_;
return &ipv4_value_;
}
// Get the size of the boolean data.
template <typename Protocol>
std::size_t size(const Protocol&) const
std::size_t size(const Protocol& protocol) const
{
return sizeof(value_);
if (protocol.family() == PF_INET6)
return sizeof(ipv6_value_);
return sizeof(ipv4_value_);
}
// Set the size of the boolean data.
template <typename Protocol>
void resize(const Protocol&, std::size_t s)
void resize(const Protocol& protocol, std::size_t s)
{
if (s != sizeof(value_))
throw std::length_error("boolean socket option resize");
if (protocol.family() == PF_INET6)
{
if (s != sizeof(ipv6_value_))
{
throw std::length_error(
"multicast_enable_loopback socket option resize");
}
ipv4_value_ = ipv6_value_ ? 1 : 0;
}
else
{
if (s != sizeof(ipv4_value_))
{
throw std::length_error(
"multicast_enable_loopback socket option resize");
}
ipv6_value_ = ipv4_value_ ? 1 : 0;
}
}
private:
value_type value_;
ipv4_value_type ipv4_value_;
ipv6_value_type ipv6_value_;
};
// Helper template for implementing unicast hops options.
@ -206,6 +237,10 @@ public:
{
if (s != sizeof(value_))
throw std::length_error("unicast hops socket option resize");
#if defined(__hpux)
if (value_ < 0)
value_ = value_ & 0xFF;
#endif
}
private:
@ -477,7 +512,7 @@ public:
}
// Construct with IPv6 interface.
explicit network_interface(unsigned long ipv6_interface)
explicit network_interface(unsigned int ipv6_interface)
{
ipv4_value_.s_addr =
asio::detail::socket_ops::host_to_network_long(
@ -523,7 +558,7 @@ public:
private:
asio::detail::in4_addr_type ipv4_value_;
unsigned long ipv6_value_;
unsigned int ipv6_value_;
};
} // namespace socket_option

View File

@ -167,7 +167,7 @@ typedef asio::ip::detail::socket_option::multicast_hops<
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined enable_loopback;
#else
typedef asio::ip::detail::socket_option::boolean<
typedef asio::ip::detail::socket_option::multicast_enable_loopback<
IPPROTO_IP, IP_MULTICAST_LOOP, IPPROTO_IPV6, IPV6_MULTICAST_LOOP>
enable_loopback;
#endif

View File

@ -27,17 +27,17 @@ namespace placeholders {
#if defined(GENERATING_DOCUMENTATION)
/// An argument placeholder, for use with @ref boost_bind, that corresponds to
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the error argument of a handler for any of the asynchronous functions.
unspecified error;
/// An argument placeholder, for use with @ref boost_bind, that corresponds to
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the bytes_transferred argument of a handler for asynchronous functions such
/// as asio::basic_stream_socket::async_write_some or
/// asio::async_write.
unspecified bytes_transferred;
/// An argument placeholder, for use with @ref boost_bind, that corresponds to
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the iterator argument of a handler for asynchronous functions such as
/// asio::basic_resolver::resolve.
unspecified iterator;

View File

@ -238,7 +238,7 @@ public:
typedef handshake_handler<Stream, Handler> connect_handler;
connect_handler* local_handler =
new connect_handler(handler, io_service());
new connect_handler(handler, get_io_service());
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
@ -259,7 +259,7 @@ public:
);
local_handler->set_operation(op);
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Shut down SSL on the stream.
@ -294,7 +294,7 @@ public:
typedef shutdown_handler<Stream, Handler> disconnect_handler;
disconnect_handler* local_handler =
new disconnect_handler(handler, io_service());
new disconnect_handler(handler, get_io_service());
openssl_operation<Stream>* op = new openssl_operation<Stream>
(
@ -313,7 +313,7 @@ public:
);
local_handler->set_operation(op);
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Write some data to the stream.
@ -354,7 +354,7 @@ public:
{
typedef io_handler<Stream, Handler> send_handler;
send_handler* local_handler = new send_handler(handler, io_service());
send_handler* local_handler = new send_handler(handler, get_io_service());
boost::function<int (SSL*)> send_func =
boost::bind(&::SSL_write, boost::arg<1>(),
@ -378,7 +378,7 @@ public:
);
local_handler->set_operation(op);
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Read some data from the stream.
@ -419,7 +419,7 @@ public:
{
typedef io_handler<Stream, Handler> recv_handler;
recv_handler* local_handler = new recv_handler(handler, io_service());
recv_handler* local_handler = new recv_handler(handler, get_io_service());
boost::function<int (SSL*)> recv_func =
boost::bind(&::SSL_read, boost::arg<1>(),
@ -443,7 +443,7 @@ public:
);
local_handler->set_operation(op);
io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
get_io_service().post(boost::bind(&openssl_operation<Stream>::start, op));
}
// Peek at the incoming data on the stream.

View File

@ -85,7 +85,7 @@ public:
template <typename Arg, typename Context_Service>
explicit stream(Arg& arg, basic_context<Context_Service>& context)
: next_layer_(arg),
service_(asio::use_service<Service>(next_layer_.io_service())),
service_(asio::use_service<Service>(next_layer_.get_io_service())),
impl_(service_.null())
{
service_.create(impl_, next_layer_, context);
@ -97,7 +97,8 @@ public:
service_.destroy(impl_, next_layer_);
}
/// Get the io_service associated with the object.
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the object.
/**
* This function may be used to obtain the io_service object that the stream
* uses to dispatch handlers for asynchronous operations.
@ -107,7 +108,20 @@ public:
*/
asio::io_service& io_service()
{
return next_layer_.io_service();
return next_layer_.get_io_service();
}
/// Get the io_service associated with the object.
/**
* This function may be used to obtain the io_service object that the stream
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that stream will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_service& get_io_service()
{
return next_layer_.get_io_service();
}
/// Get a reference to the next layer.

View File

@ -65,7 +65,8 @@ public:
service_.destroy(impl_);
}
/// Get the io_service associated with the strand.
/// (Deprecated: use get_io_service().) Get the io_service associated with
/// the strand.
/**
* This function may be used to obtain the io_service object that the strand
* uses to dispatch handlers for asynchronous operations.
@ -75,7 +76,20 @@ public:
*/
asio::io_service& io_service()
{
return service_.io_service();
return service_.get_io_service();
}
/// Get the io_service associated with the strand.
/**
* This function may be used to obtain the io_service object that the strand
* uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_service object that the strand will use to
* dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_service& get_io_service()
{
return service_.get_io_service();
}
/// Request the strand to invoke the given handler.