|
Boost-Commit : |
From: chris_at_[hidden]
Date: 2008-05-05 02:30:15
Author: chris_kohlhoff
Date: 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
New Revision: 45122
URL: http://svn.boost.org/trac/boost/changeset/45122
Log:
Implement custom memory allocation support for reactor-based asynchronous operations.
Added:
trunk/boost/asio/detail/handler_base_from_member.hpp (contents, props changed)
Text files modified:
trunk/boost/asio/detail/dev_poll_reactor.hpp | 68 +++++++----
trunk/boost/asio/detail/epoll_reactor.hpp | 76 ++++++++-----
trunk/boost/asio/detail/hash_map.hpp | 34 +++++
trunk/boost/asio/detail/kqueue_reactor.hpp | 84 +++++++++-----
trunk/boost/asio/detail/reactive_descriptor_service.hpp | 87 +++++++++------
trunk/boost/asio/detail/reactive_socket_service.hpp | 220 ++++++++++++++++++++++-----------------
trunk/boost/asio/detail/reactor_op_queue.hpp | 199 +++++++++++++++++++++++-------------
trunk/boost/asio/detail/select_reactor.hpp | 53 +++++---
trunk/boost/asio/detail/win_iocp_socket_service.hpp | 56 +++++----
trunk/boost/asio/detail/wrapped_handler.hpp | 48 +++++--
10 files changed, 572 insertions(+), 353 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 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -142,9 +142,18 @@
return;
if (allow_speculative_read)
+ {
if (!read_op_queue_.has_operation(descriptor))
- if (handler(boost::system::error_code()))
+ {
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
+ }
+ }
if (read_op_queue_.enqueue_operation(descriptor, handler))
{
@@ -170,9 +179,18 @@
return;
if (allow_speculative_write)
+ {
if (!write_op_queue_.has_operation(descriptor))
- if (handler(boost::system::error_code()))
+ {
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
+ }
+ }
if (write_op_queue_.enqueue_operation(descriptor, handler))
{
@@ -313,16 +331,16 @@
// Dispatch any operation cancellations that were made while the select
// loop was not running.
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
- except_op_queue_.dispatch_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
+ except_op_queue_.perform_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
timer_queues_[i]->dispatch_cancellations();
// Check if the thread is supposed to stop.
if (stop_thread_)
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -331,7 +349,7 @@
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
&& except_op_queue_.empty() && all_timer_queues_are_empty())
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -347,9 +365,9 @@
int descriptor = pending_event_changes_[i].fd;
boost::system::error_code ec = boost::system::error_code(
errno, boost::asio::error::get_system_category());
- read_op_queue_.dispatch_all_operations(descriptor, ec);
- write_op_queue_.dispatch_all_operations(descriptor, ec);
- except_op_queue_.dispatch_all_operations(descriptor, ec);
+ read_op_queue_.perform_all_operations(descriptor, ec);
+ write_op_queue_.perform_all_operations(descriptor, ec);
+ except_op_queue_.perform_all_operations(descriptor, ec);
}
}
pending_event_changes_.clear();
@@ -370,7 +388,7 @@
lock.lock();
wait_in_progress_ = false;
- // Block signals while dispatching operations.
+ // Block signals while performing operations.
boost::asio::detail::signal_blocker sb;
// Dispatch the waiting events.
@@ -391,17 +409,17 @@
// Exception operations must be processed first to ensure that any
// out-of-band data is read before normal data.
if (events[i].events & (POLLPRI | POLLERR | POLLHUP))
- more_except = except_op_queue_.dispatch_operation(descriptor, ec);
+ more_except = except_op_queue_.perform_operation(descriptor, ec);
else
more_except = except_op_queue_.has_operation(descriptor);
if (events[i].events & (POLLIN | POLLERR | POLLHUP))
- more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
+ more_reads = read_op_queue_.perform_operation(descriptor, ec);
else
more_reads = read_op_queue_.has_operation(descriptor);
if (events[i].events & (POLLOUT | POLLERR | POLLHUP))
- more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
+ more_writes = write_op_queue_.perform_operation(descriptor, ec);
else
more_writes = write_op_queue_.has_operation(descriptor);
@@ -436,16 +454,16 @@
{
ec = boost::system::error_code(errno,
boost::asio::error::get_system_category());
- read_op_queue_.dispatch_all_operations(descriptor, ec);
- write_op_queue_.dispatch_all_operations(descriptor, ec);
- except_op_queue_.dispatch_all_operations(descriptor, ec);
+ read_op_queue_.perform_all_operations(descriptor, ec);
+ write_op_queue_.perform_all_operations(descriptor, ec);
+ except_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
}
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
- except_op_queue_.dispatch_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
+ except_op_queue_.perform_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
timer_queues_[i]->dispatch_timers();
@@ -457,7 +475,7 @@
cancel_ops_unlocked(pending_cancellations_[i]);
pending_cancellations_.clear();
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
}
// Run the select loop in the thread.
@@ -557,14 +575,14 @@
// destructors may make calls back into this reactor. We make a copy of the
// vector of timer queues since the original may be modified while the lock
// is not held.
- void cleanup_operations_and_timers(
+ void complete_operations_and_cleanup_timers(
boost::asio::detail::mutex::scoped_lock& lock)
{
timer_queues_for_cleanup_ = timer_queues_;
lock.unlock();
- read_op_queue_.cleanup_operations();
- write_op_queue_.cleanup_operations();
- except_op_queue_.cleanup_operations();
+ read_op_queue_.complete_operations();
+ write_op_queue_.complete_operations();
+ except_op_queue_.complete_operations();
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
timer_queues_for_cleanup_[i]->cleanup_timers();
}
Modified: trunk/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor.hpp (original)
+++ trunk/boost/asio/detail/epoll_reactor.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -152,8 +152,13 @@
{
if (allow_speculative_read && descriptor_data.allow_speculative_read)
{
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
// We only get one shot at a speculative read in this function.
allow_speculative_read = false;
@@ -171,8 +176,13 @@
// Speculative reads are ok as there are no queued read operations.
descriptor_data.allow_speculative_read = true;
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
}
// Speculative reads are not ok as there will be queued read operations.
@@ -195,7 +205,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- read_op_queue_.dispatch_all_operations(descriptor, ec);
+ read_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -209,8 +219,13 @@
{
if (allow_speculative_write && descriptor_data.allow_speculative_write)
{
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
// We only get one shot at a speculative write in this function.
allow_speculative_write = false;
@@ -228,8 +243,13 @@
// Speculative writes are ok as there are no queued write operations.
descriptor_data.allow_speculative_write = true;
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
}
// Speculative writes are not ok as there will be queued write operations.
@@ -252,7 +272,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- write_op_queue_.dispatch_all_operations(descriptor, ec);
+ write_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -285,7 +305,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- except_op_queue_.dispatch_all_operations(descriptor, ec);
+ except_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -322,7 +342,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- write_op_queue_.dispatch_all_operations(descriptor, ec);
+ write_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -407,16 +427,16 @@
// Dispatch any operation cancellations that were made while the select
// loop was not running.
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
- except_op_queue_.dispatch_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
+ except_op_queue_.perform_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
timer_queues_[i]->dispatch_cancellations();
// Check if the thread is supposed to stop.
if (stop_thread_)
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -425,7 +445,7 @@
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
&& except_op_queue_.empty() && all_timer_queues_are_empty())
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -442,7 +462,7 @@
lock.lock();
wait_in_progress_ = false;
- // Block signals while dispatching operations.
+ // Block signals while performing operations.
boost::asio::detail::signal_blocker sb;
// Dispatch the waiting events.
@@ -463,17 +483,17 @@
// Exception operations must be processed first to ensure that any
// out-of-band data is read before normal data.
if (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))
- more_except = except_op_queue_.dispatch_operation(descriptor, ec);
+ more_except = except_op_queue_.perform_operation(descriptor, ec);
else
more_except = except_op_queue_.has_operation(descriptor);
if (events[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
- more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
+ more_reads = read_op_queue_.perform_operation(descriptor, ec);
else
more_reads = read_op_queue_.has_operation(descriptor);
if (events[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
- more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
+ more_writes = write_op_queue_.perform_operation(descriptor, ec);
else
more_writes = write_op_queue_.has_operation(descriptor);
@@ -507,16 +527,16 @@
{
ec = boost::system::error_code(errno,
boost::asio::error::get_system_category());
- read_op_queue_.dispatch_all_operations(descriptor, ec);
- write_op_queue_.dispatch_all_operations(descriptor, ec);
- except_op_queue_.dispatch_all_operations(descriptor, ec);
+ read_op_queue_.perform_all_operations(descriptor, ec);
+ write_op_queue_.perform_all_operations(descriptor, ec);
+ except_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
}
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
- except_op_queue_.dispatch_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
+ except_op_queue_.perform_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
timer_queues_[i]->dispatch_timers();
@@ -532,7 +552,7 @@
need_epoll_wait_ = !read_op_queue_.empty()
|| !write_op_queue_.empty() || !except_op_queue_.empty();
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
}
// Run the select loop in the thread.
@@ -635,14 +655,14 @@
// destructors may make calls back into this reactor. We make a copy of the
// vector of timer queues since the original may be modified while the lock
// is not held.
- void cleanup_operations_and_timers(
+ void complete_operations_and_cleanup_timers(
boost::asio::detail::mutex::scoped_lock& lock)
{
timer_queues_for_cleanup_ = timer_queues_;
lock.unlock();
- read_op_queue_.cleanup_operations();
- write_op_queue_.cleanup_operations();
- except_op_queue_.cleanup_operations();
+ read_op_queue_.complete_operations();
+ write_op_queue_.complete_operations();
+ except_op_queue_.complete_operations();
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
timer_queues_for_cleanup_[i]->cleanup_timers();
}
Added: trunk/boost/asio/detail/handler_base_from_member.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/handler_base_from_member.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -0,0 +1,78 @@
+//
+// handler_base_from_member.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Base class for classes that need a handler data member. Forwards the custom
+// allocation and invocation hooks to the contained handler.
+template <typename Handler>
+class handler_base_from_member
+{
+public:
+ handler_base_from_member(Handler handler)
+ : handler_(handler)
+ {
+ }
+
+//protected:
+ Handler handler_;
+
+protected:
+ // Protected destructor to prevent deletion through this type.
+ ~handler_base_from_member()
+ {
+ }
+};
+
+template <typename Handler>
+inline void* asio_handler_allocate(std::size_t size,
+ handler_base_from_member<Handler>* this_handler)
+{
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, &this_handler->handler_);
+}
+
+template <typename Handler>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ handler_base_from_member<Handler>* this_handler)
+{
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, &this_handler->handler_);
+}
+
+template <typename Function, typename Handler>
+inline void asio_handler_invoke(const Function& function,
+ handler_base_from_member<Handler>* this_handler)
+{
+ boost_asio_handler_invoke_helpers::invoke(
+ function, &this_handler->handler_);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP
Modified: trunk/boost/asio/detail/hash_map.hpp
==============================================================================
--- trunk/boost/asio/detail/hash_map.hpp (original)
+++ trunk/boost/asio/detail/hash_map.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -44,6 +44,7 @@
}
#endif // defined(_WIN64)
+// Note: assumes K and V are POD types.
template <typename K, typename V>
class hash_map
: private noncopyable
@@ -140,7 +141,7 @@
if (it == values_.end())
{
buckets_[bucket].first = buckets_[bucket].last =
- values_.insert(values_.end(), v);
+ values_insert(values_.end(), v);
return std::pair<iterator, bool>(buckets_[bucket].last, true);
}
iterator end = buckets_[bucket].last;
@@ -151,7 +152,7 @@
return std::pair<iterator, bool>(it, false);
++it;
}
- buckets_[bucket].last = values_.insert(end, v);
+ buckets_[bucket].last = values_insert(end, v);
return std::pair<iterator, bool>(buckets_[bucket].last, true);
}
@@ -170,7 +171,7 @@
else if (is_last)
--buckets_[bucket].last;
- values_.erase(it);
+ values_erase(it);
}
// Remove all entries from the map.
@@ -185,9 +186,36 @@
}
private:
+ // Insert an element into the values list by splicing from the spares list,
+ // if a spare is available, and otherwise by inserting a new element.
+ iterator values_insert(iterator it, const value_type& v)
+ {
+ if (spares_.empty())
+ {
+ return values_.insert(it, v);
+ }
+ else
+ {
+ spares_.front() = v;
+ values_.splice(it, spares_, spares_.begin());
+ return --it;
+ }
+ }
+
+ // Erase an element from the values list by splicing it to the spares list.
+ void values_erase(iterator it)
+ {
+ *it = value_type();
+ spares_.splice(spares_.begin(), values_, it);
+ }
+
// The list of all values in the hash map.
std::list<value_type> values_;
+ // The list of spare nodes waiting to be recycled. Assumes that POD types only
+ // are stored in the hash map.
+ std::list<value_type> spares_;
+
// The type for a bucket in the hash table.
struct bucket_type
{
Modified: trunk/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/kqueue_reactor.hpp (original)
+++ trunk/boost/asio/detail/kqueue_reactor.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -151,8 +151,13 @@
{
if (allow_speculative_read && descriptor_data.allow_speculative_read)
{
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
// We only get one shot at a speculative read in this function.
allow_speculative_read = false;
@@ -170,8 +175,13 @@
// Speculative reads are ok as there are no queued read operations.
descriptor_data.allow_speculative_read = true;
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
}
// Speculative reads are not ok as there will be queued read operations.
@@ -185,7 +195,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- read_op_queue_.dispatch_all_operations(descriptor, ec);
+ read_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -199,8 +209,13 @@
{
if (allow_speculative_write && descriptor_data.allow_speculative_write)
{
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
// We only get one shot at a speculative write in this function.
allow_speculative_write = false;
@@ -218,8 +233,13 @@
// Speculative writes are ok as there are no queued write operations.
descriptor_data.allow_speculative_write = true;
- if (handler(boost::system::error_code()))
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = 0;
+ if (handler.perform(ec, bytes_transferred))
+ {
+ handler.complete(ec, bytes_transferred);
return;
+ }
}
// Speculative writes are not ok as there will be queued write operations.
@@ -233,7 +253,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- write_op_queue_.dispatch_all_operations(descriptor, ec);
+ write_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -260,7 +280,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- except_op_queue_.dispatch_all_operations(descriptor, ec);
+ except_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -287,7 +307,7 @@
{
boost::system::error_code ec(errno,
boost::asio::error::get_system_category());
- write_op_queue_.dispatch_all_operations(descriptor, ec);
+ write_op_queue_.perform_all_operations(descriptor, ec);
}
}
}
@@ -374,16 +394,16 @@
// Dispatch any operation cancellations that were made while the select
// loop was not running.
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
- except_op_queue_.dispatch_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
+ except_op_queue_.perform_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
timer_queues_[i]->dispatch_cancellations();
// Check if the thread is supposed to stop.
if (stop_thread_)
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -392,7 +412,7 @@
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
&& except_op_queue_.empty() && all_timer_queues_are_empty())
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -412,7 +432,7 @@
lock.lock();
wait_in_progress_ = false;
- // Block signals while dispatching operations.
+ // Block signals while performing operations.
boost::asio::detail::signal_blocker sb;
// Dispatch the waiting events.
@@ -432,22 +452,22 @@
{
boost::system::error_code error(
events[i].data, boost::asio::error::get_system_category());
- except_op_queue_.dispatch_all_operations(descriptor, error);
- read_op_queue_.dispatch_all_operations(descriptor, error);
+ except_op_queue_.perform_all_operations(descriptor, error);
+ read_op_queue_.perform_all_operations(descriptor, error);
}
else if (events[i].flags & EV_OOBAND)
{
boost::system::error_code error;
- more_except = except_op_queue_.dispatch_operation(descriptor, error);
+ more_except = except_op_queue_.perform_operation(descriptor, error);
if (events[i].data > 0)
- more_reads = read_op_queue_.dispatch_operation(descriptor, error);
+ more_reads = read_op_queue_.perform_operation(descriptor, error);
else
more_reads = read_op_queue_.has_operation(descriptor);
}
else
{
boost::system::error_code error;
- more_reads = read_op_queue_.dispatch_operation(descriptor, error);
+ more_reads = read_op_queue_.perform_operation(descriptor, error);
more_except = except_op_queue_.has_operation(descriptor);
}
@@ -463,8 +483,8 @@
{
boost::system::error_code error(errno,
boost::asio::error::get_system_category());
- except_op_queue_.dispatch_all_operations(descriptor, error);
- read_op_queue_.dispatch_all_operations(descriptor, error);
+ except_op_queue_.perform_all_operations(descriptor, error);
+ read_op_queue_.perform_all_operations(descriptor, error);
}
}
else if (events[i].filter == EVFILT_WRITE)
@@ -475,12 +495,12 @@
{
boost::system::error_code error(
events[i].data, boost::asio::error::get_system_category());
- write_op_queue_.dispatch_all_operations(descriptor, error);
+ write_op_queue_.perform_all_operations(descriptor, error);
}
else
{
boost::system::error_code error;
- more_writes = write_op_queue_.dispatch_operation(descriptor, error);
+ more_writes = write_op_queue_.perform_operation(descriptor, error);
}
// Update the descriptor in the kqueue.
@@ -493,14 +513,14 @@
{
boost::system::error_code error(errno,
boost::asio::error::get_system_category());
- write_op_queue_.dispatch_all_operations(descriptor, error);
+ write_op_queue_.perform_all_operations(descriptor, error);
}
}
}
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
- except_op_queue_.dispatch_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
+ except_op_queue_.perform_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
timer_queues_[i]->dispatch_timers();
@@ -516,7 +536,7 @@
need_kqueue_wait_ = !read_op_queue_.empty()
|| !write_op_queue_.empty() || !except_op_queue_.empty();
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
}
// Run the select loop in the thread.
@@ -617,14 +637,14 @@
// destructors may make calls back into this reactor. We make a copy of the
// vector of timer queues since the original may be modified while the lock
// is not held.
- void cleanup_operations_and_timers(
+ void complete_operations_and_cleanup_timers(
boost::asio::detail::mutex::scoped_lock& lock)
{
timer_queues_for_cleanup_ = timer_queues_;
lock.unlock();
- read_op_queue_.cleanup_operations();
- write_op_queue_.cleanup_operations();
- except_op_queue_.cleanup_operations();
+ read_op_queue_.complete_operations();
+ write_op_queue_.complete_operations();
+ except_op_queue_.complete_operations();
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
timer_queues_for_cleanup_[i]->cleanup_timers();
}
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 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -21,6 +21,7 @@
#include <boost/asio/error.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/handler_base_from_member.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/service_base.hpp>
#include <boost/asio/detail/descriptor_ops.hpp>
@@ -309,25 +310,27 @@
}
template <typename ConstBufferSequence, typename Handler>
- class write_handler
+ class write_operation :
+ public handler_base_from_member<Handler>
{
public:
- write_handler(int descriptor, boost::asio::io_service& io_service,
+ write_operation(int descriptor, boost::asio::io_service& io_service,
const ConstBufferSequence& buffers, Handler handler)
- : descriptor_(descriptor),
+ : handler_base_from_member<Handler>(handler),
+ descriptor_(descriptor),
io_service_(io_service),
work_(io_service),
- buffers_(buffers),
- handler_(handler)
+ buffers_(buffers)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether the operation was successful.
- if (result)
+ if (ec)
{
- io_service_.post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
@@ -345,7 +348,6 @@
}
// Write the data.
- boost::system::error_code ec;
int bytes = descriptor_ops::gather_write(descriptor_, bufs, i, ec);
// Check if we need to run the operation again.
@@ -353,16 +355,21 @@
|| ec == boost::asio::error::try_again)
return false;
- io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes));
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
+ }
+
private:
int descriptor_;
boost::asio::io_service& io_service_;
boost::asio::io_service::work work_;
ConstBufferSequence buffers_;
- Handler handler_;
};
// Start an asynchronous write. The data being sent must be valid for the
@@ -411,30 +418,38 @@
}
reactor_.start_write_op(impl.descriptor_, impl.reactor_data_,
- write_handler<ConstBufferSequence, Handler>(
+ write_operation<ConstBufferSequence, Handler>(
impl.descriptor_, this->get_io_service(), buffers, handler));
}
}
template <typename Handler>
- class null_buffers_handler
+ class null_buffers_operation :
+ public handler_base_from_member<Handler>
{
public:
- null_buffers_handler(boost::asio::io_service& io_service, Handler handler)
- : work_(io_service),
- handler_(handler)
+ null_buffers_operation(boost::asio::io_service& io_service, Handler handler)
+ : handler_base_from_member<Handler>(handler),
+ work_(io_service)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code&,
+ std::size_t& bytes_transferred)
{
- work_.get_io_service().post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ work_.get_io_service().post(bind_handler(
+ this->handler_, ec, bytes_transferred));
+ }
+
private:
boost::asio::io_service::work work_;
- Handler handler_;
};
// Start an asynchronous wait until data can be written without blocking.
@@ -450,7 +465,7 @@
else
{
reactor_.start_write_op(impl.descriptor_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -547,25 +562,27 @@
}
template <typename MutableBufferSequence, typename Handler>
- class read_handler
+ class read_operation :
+ public handler_base_from_member<Handler>
{
public:
- read_handler(int descriptor, boost::asio::io_service& io_service,
+ read_operation(int descriptor, boost::asio::io_service& io_service,
const MutableBufferSequence& buffers, Handler handler)
- : descriptor_(descriptor),
+ : handler_base_from_member<Handler>(handler),
+ descriptor_(descriptor),
io_service_(io_service),
work_(io_service),
- buffers_(buffers),
- handler_(handler)
+ buffers_(buffers)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether the operation was successful.
- if (result)
+ if (ec)
{
- io_service_.post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
@@ -583,7 +600,6 @@
}
// Read some data.
- boost::system::error_code ec;
int bytes = descriptor_ops::scatter_read(descriptor_, bufs, i, ec);
if (bytes == 0)
ec = boost::asio::error::eof;
@@ -593,16 +609,21 @@
|| ec == boost::asio::error::try_again)
return false;
- io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes));
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
+ }
+
private:
int descriptor_;
boost::asio::io_service& io_service_;
boost::asio::io_service::work work_;
MutableBufferSequence buffers_;
- Handler handler_;
};
// Start an asynchronous read. The buffer for the data being read must be
@@ -651,7 +672,7 @@
}
reactor_.start_read_op(impl.descriptor_, impl.reactor_data_,
- read_handler<MutableBufferSequence, Handler>(
+ read_operation<MutableBufferSequence, Handler>(
impl.descriptor_, this->get_io_service(), buffers, handler));
}
}
@@ -669,7 +690,7 @@
else
{
reactor_.start_read_op(impl.descriptor_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
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 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -26,6 +26,7 @@
#include <boost/asio/io_service.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/handler_base_from_member.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/service_base.hpp>
#include <boost/asio/detail/socket_holder.hpp>
@@ -580,27 +581,29 @@
}
template <typename ConstBufferSequence, typename Handler>
- class send_handler
+ class send_operation :
+ public handler_base_from_member<Handler>
{
public:
- send_handler(socket_type socket, boost::asio::io_service& io_service,
+ send_operation(socket_type socket, boost::asio::io_service& io_service,
const ConstBufferSequence& buffers, socket_base::message_flags flags,
Handler handler)
- : socket_(socket),
+ : handler_base_from_member<Handler>(handler),
+ socket_(socket),
io_service_(io_service),
work_(io_service),
buffers_(buffers),
- flags_(flags),
- handler_(handler)
+ flags_(flags)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether the operation was successful.
- if (result)
+ if (ec)
{
- io_service_.post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
@@ -618,7 +621,6 @@
}
// Send the data.
- boost::system::error_code ec;
int bytes = socket_ops::send(socket_, bufs, i, flags_, ec);
// Check if we need to run the operation again.
@@ -626,17 +628,22 @@
|| ec == boost::asio::error::try_again)
return false;
- io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes));
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
+ }
+
private:
socket_type socket_;
boost::asio::io_service& io_service_;
boost::asio::io_service::work work_;
ConstBufferSequence buffers_;
socket_base::message_flags flags_;
- Handler handler_;
};
// Start an asynchronous send. The data being sent must be valid for the
@@ -688,30 +695,38 @@
}
reactor_.start_write_op(impl.socket_, impl.reactor_data_,
- send_handler<ConstBufferSequence, Handler>(
+ send_operation<ConstBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers, flags, handler));
}
}
template <typename Handler>
- class null_buffers_handler
+ class null_buffers_operation :
+ public handler_base_from_member<Handler>
{
public:
- null_buffers_handler(boost::asio::io_service& io_service, Handler handler)
- : work_(io_service),
- handler_(handler)
+ null_buffers_operation(boost::asio::io_service& io_service, Handler handler)
+ : handler_base_from_member<Handler>(handler),
+ work_(io_service)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code&,
+ std::size_t& bytes_transferred)
{
- work_.get_io_service().post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ work_.get_io_service().post(bind_handler(
+ this->handler_, ec, bytes_transferred));
+ }
+
private:
boost::asio::io_service::work work_;
- Handler handler_;
};
// Start an asynchronous wait until data can be sent without blocking.
@@ -727,7 +742,7 @@
else
{
reactor_.start_write_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -811,28 +826,30 @@
}
template <typename ConstBufferSequence, typename Handler>
- class send_to_handler
+ class send_to_operation :
+ public handler_base_from_member<Handler>
{
public:
- send_to_handler(socket_type socket, boost::asio::io_service& io_service,
+ send_to_operation(socket_type socket, boost::asio::io_service& io_service,
const ConstBufferSequence& buffers, const endpoint_type& endpoint,
socket_base::message_flags flags, Handler handler)
- : socket_(socket),
+ : handler_base_from_member<Handler>(handler),
+ socket_(socket),
io_service_(io_service),
work_(io_service),
buffers_(buffers),
destination_(endpoint),
- flags_(flags),
- handler_(handler)
+ flags_(flags)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether the operation was successful.
- if (result)
+ if (ec)
{
- io_service_.post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
@@ -850,7 +867,6 @@
}
// Send the data.
- boost::system::error_code ec;
int bytes = socket_ops::sendto(socket_, bufs, i, flags_,
destination_.data(), destination_.size(), ec);
@@ -859,10 +875,16 @@
|| ec == boost::asio::error::try_again)
return false;
- io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes));
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
+ }
+
private:
socket_type socket_;
boost::asio::io_service& io_service_;
@@ -870,7 +892,6 @@
ConstBufferSequence buffers_;
endpoint_type destination_;
socket_base::message_flags flags_;
- Handler handler_;
};
// Start an asynchronous send. The data being sent must be valid for the
@@ -902,7 +923,7 @@
}
reactor_.start_write_op(impl.socket_, impl.reactor_data_,
- send_to_handler<ConstBufferSequence, Handler>(
+ send_to_operation<ConstBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers,
destination, flags, handler));
}
@@ -921,7 +942,7 @@
else
{
reactor_.start_write_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -1018,27 +1039,29 @@
}
template <typename MutableBufferSequence, typename Handler>
- class receive_handler
+ class receive_operation :
+ public handler_base_from_member<Handler>
{
public:
- receive_handler(socket_type socket, boost::asio::io_service& io_service,
+ receive_operation(socket_type socket, boost::asio::io_service& io_service,
const MutableBufferSequence& buffers, socket_base::message_flags flags,
Handler handler)
- : socket_(socket),
+ : handler_base_from_member<Handler>(handler),
+ socket_(socket),
io_service_(io_service),
work_(io_service),
buffers_(buffers),
- flags_(flags),
- handler_(handler)
+ flags_(flags)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether the operation was successful.
- if (result)
+ if (ec)
{
- io_service_.post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
@@ -1056,7 +1079,6 @@
}
// Receive some data.
- boost::system::error_code ec;
int bytes = socket_ops::recv(socket_, bufs, i, flags_, ec);
if (bytes == 0)
ec = boost::asio::error::eof;
@@ -1066,17 +1088,22 @@
|| ec == boost::asio::error::try_again)
return false;
- io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes));
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
+ }
+
private:
socket_type socket_;
boost::asio::io_service& io_service_;
boost::asio::io_service::work work_;
MutableBufferSequence buffers_;
socket_base::message_flags flags_;
- Handler handler_;
};
// Start an asynchronous receive. The buffer for the data being received
@@ -1131,13 +1158,13 @@
if (flags & socket_base::message_out_of_band)
{
reactor_.start_except_op(impl.socket_, impl.reactor_data_,
- receive_handler<MutableBufferSequence, Handler>(
+ receive_operation<MutableBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers, flags, handler));
}
else
{
reactor_.start_read_op(impl.socket_, impl.reactor_data_,
- receive_handler<MutableBufferSequence, Handler>(
+ receive_operation<MutableBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers, flags, handler));
}
}
@@ -1156,12 +1183,12 @@
else if (flags & socket_base::message_out_of_band)
{
reactor_.start_except_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler));
+ null_buffers_operation<Handler>(this->get_io_service(), handler));
}
else
{
reactor_.start_read_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -1260,29 +1287,31 @@
}
template <typename MutableBufferSequence, typename Handler>
- class receive_from_handler
+ class receive_from_operation :
+ public handler_base_from_member<Handler>
{
public:
- receive_from_handler(socket_type socket,
+ receive_from_operation(socket_type socket,
boost::asio::io_service& io_service,
const MutableBufferSequence& buffers, endpoint_type& endpoint,
socket_base::message_flags flags, Handler handler)
- : socket_(socket),
+ : handler_base_from_member<Handler>(handler),
+ socket_(socket),
io_service_(io_service),
work_(io_service),
buffers_(buffers),
sender_endpoint_(endpoint),
- flags_(flags),
- handler_(handler)
+ flags_(flags)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether the operation was successful.
- if (result)
+ if (ec)
{
- io_service_.post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
@@ -1301,7 +1330,6 @@
// Receive some data.
std::size_t addr_len = sender_endpoint_.capacity();
- boost::system::error_code ec;
int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_,
sender_endpoint_.data(), &addr_len, ec);
if (bytes == 0)
@@ -1313,10 +1341,16 @@
return false;
sender_endpoint_.resize(addr_len);
- io_service_.post(bind_handler(handler_, ec, bytes < 0 ? 0 : bytes));
+ bytes_transferred = (bytes < 0 ? 0 : bytes);
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
+ }
+
private:
socket_type socket_;
boost::asio::io_service& io_service_;
@@ -1324,7 +1358,6 @@
MutableBufferSequence buffers_;
endpoint_type& sender_endpoint_;
socket_base::message_flags flags_;
- Handler handler_;
};
// Start an asynchronous receive. The buffer for the data being received and
@@ -1356,7 +1389,7 @@
}
reactor_.start_read_op(impl.socket_, impl.reactor_data_,
- receive_from_handler<MutableBufferSequence, Handler>(
+ receive_from_operation<MutableBufferSequence, Handler>(
impl.socket_, this->get_io_service(), buffers,
sender_endpoint, flags, handler));
}
@@ -1381,12 +1414,12 @@
if (flags & socket_base::message_out_of_band)
{
reactor_.start_except_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler));
+ null_buffers_operation<Handler>(this->get_io_service(), handler));
}
else
{
reactor_.start_read_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -1483,35 +1516,32 @@
}
template <typename Socket, typename Handler>
- class accept_handler
+ class accept_operation :
+ public handler_base_from_member<Handler>
{
public:
- accept_handler(socket_type socket, boost::asio::io_service& io_service,
+ accept_operation(socket_type socket, boost::asio::io_service& io_service,
Socket& peer, const protocol_type& protocol,
endpoint_type* peer_endpoint, bool enable_connection_aborted,
Handler handler)
- : socket_(socket),
+ : handler_base_from_member<Handler>(handler),
+ socket_(socket),
io_service_(io_service),
work_(io_service),
peer_(peer),
protocol_(protocol),
peer_endpoint_(peer_endpoint),
- enable_connection_aborted_(enable_connection_aborted),
- handler_(handler)
+ enable_connection_aborted_(enable_connection_aborted)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec, std::size_t&)
{
// Check whether the operation was successful.
- if (result)
- {
- io_service_.post(bind_handler(handler_, result));
+ if (ec)
return true;
- }
// Accept the waiting connection.
- boost::system::error_code ec;
socket_holder new_socket;
std::size_t addr_len = 0;
if (peer_endpoint_)
@@ -1547,10 +1577,14 @@
new_socket.release();
}
- io_service_.post(bind_handler(handler_, ec));
return true;
}
+ void complete(const boost::system::error_code& ec, std::size_t)
+ {
+ io_service_.post(bind_handler(this->handler_, ec));
+ }
+
private:
socket_type socket_;
boost::asio::io_service& io_service_;
@@ -1559,7 +1593,6 @@
protocol_type protocol_;
endpoint_type* peer_endpoint_;
bool enable_connection_aborted_;
- Handler handler_;
};
// Start an asynchronous accept. The peer and peer_endpoint objects
@@ -1594,7 +1627,7 @@
}
reactor_.start_read_op(impl.socket_, impl.reactor_data_,
- accept_handler<Socket, Handler>(
+ accept_operation<Socket, Handler>(
impl.socket_, this->get_io_service(),
peer, impl.protocol_, peer_endpoint,
(impl.flags_ & implementation_type::enable_connection_aborted) != 0,
@@ -1628,57 +1661,52 @@
}
template <typename Handler>
- class connect_handler
+ class connect_operation :
+ public handler_base_from_member<Handler>
{
public:
- connect_handler(socket_type socket,
+ connect_operation(socket_type socket,
boost::asio::io_service& io_service, Handler handler)
- : socket_(socket),
+ : handler_base_from_member<Handler>(handler),
+ socket_(socket),
io_service_(io_service),
- work_(io_service),
- handler_(handler)
+ work_(io_service)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec, std::size_t&)
{
// Check whether the operation was successful.
- if (result)
- {
- io_service_.post(bind_handler(handler_, result));
+ if (ec)
return true;
- }
// Get the error code from the connect operation.
int connect_error = 0;
size_t connect_error_len = sizeof(connect_error);
- boost::system::error_code ec;
if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR,
&connect_error, &connect_error_len, ec) == socket_error_retval)
- {
- io_service_.post(bind_handler(handler_, ec));
return true;
- }
- // If connection failed then post the handler with the error code.
+ // The connection failed so the handler will be posted with an error code.
if (connect_error)
{
ec = boost::system::error_code(connect_error,
boost::asio::error::get_system_category());
- io_service_.post(bind_handler(handler_, ec));
return true;
}
- // Post the result of the successful connection operation.
- io_service_.post(bind_handler(handler_, ec));
return true;
}
+ void complete(const boost::system::error_code& ec, std::size_t)
+ {
+ io_service_.post(bind_handler(this->handler_, ec));
+ }
+
private:
socket_type socket_;
boost::asio::io_service& io_service_;
boost::asio::io_service::work work_;
- Handler handler_;
};
// Start an asynchronous connect.
@@ -1723,7 +1751,7 @@
// The connection is happening in the background, and we need to wait
// until the socket becomes writeable.
reactor_.start_connect_op(impl.socket_, impl.reactor_data_,
- connect_handler<Handler>(impl.socket_,
+ connect_operation<Handler>(impl.socket_,
this->get_io_service(), handler));
}
else
Modified: trunk/boost/asio/detail/reactor_op_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/reactor_op_queue.hpp (original)
+++ trunk/boost/asio/detail/reactor_op_queue.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -22,6 +22,7 @@
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/hash_map.hpp>
#include <boost/asio/detail/noncopyable.hpp>
@@ -38,36 +39,42 @@
reactor_op_queue()
: operations_(),
cancelled_operations_(0),
- cleanup_operations_(0)
+ complete_operations_(0)
{
}
// Add a new operation to the queue. Returns true if this is the only
// operation for the given descriptor, in which case the reactor's event
// demultiplexing function call may need to be interrupted and restarted.
- template <typename Handler>
- bool enqueue_operation(Descriptor descriptor, Handler handler)
+ template <typename Operation>
+ bool enqueue_operation(Descriptor descriptor, Operation operation)
{
- op_base* new_op = new op<Handler>(descriptor, handler);
+ // Allocate and construct an object to wrap the handler.
+ typedef handler_alloc_traits<Operation, op<Operation> > alloc_traits;
+ raw_handler_ptr<alloc_traits> raw_ptr(operation);
+ handler_ptr<alloc_traits> ptr(raw_ptr, descriptor, operation);
typedef typename operation_map::iterator iterator;
typedef typename operation_map::value_type value_type;
std::pair<iterator, bool> entry =
- operations_.insert(value_type(descriptor, new_op));
+ operations_.insert(value_type(descriptor, ptr.get()));
if (entry.second)
+ {
+ ptr.release();
return true;
+ }
op_base* current_op = entry.first->second;
while (current_op->next_)
current_op = current_op->next_;
- current_op->next_ = new_op;
+ current_op->next_ = ptr.release();
return false;
}
// Cancel all operations associated with the descriptor. Any operations
// pending for the descriptor will be notified that they have been cancelled
- // next time dispatch_cancellations is called. Returns true if any operations
+ // next time perform_cancellations is called. Returns true if any operations
// were cancelled, in which case the reactor's event demultiplexing function
// may need to be interrupted and restarted.
bool cancel_operations(Descriptor descriptor)
@@ -99,9 +106,9 @@
return operations_.find(descriptor) != operations_.end();
}
- // Dispatch the first operation corresponding to the descriptor. Returns true
+ // Perform the first operation corresponding to the descriptor. Returns true
// if there are more operations queued for the descriptor.
- bool dispatch_operation(Descriptor descriptor,
+ bool perform_operation(Descriptor descriptor,
const boost::system::error_code& result)
{
typename operation_map::iterator i = operations_.find(descriptor);
@@ -109,9 +116,9 @@
{
op_base* this_op = i->second;
i->second = this_op->next_;
- this_op->next_ = cleanup_operations_;
- cleanup_operations_ = this_op;
- bool done = this_op->invoke(result);
+ this_op->next_ = complete_operations_;
+ complete_operations_ = this_op;
+ bool done = this_op->perform(result);
if (done)
{
// Operation has finished.
@@ -128,8 +135,8 @@
else
{
// Operation wants to be called again. Leave it at the front of the
- // queue for this descriptor, and remove from the cleanup list.
- cleanup_operations_ = this_op->next_;
+ // queue for this descriptor, and remove from the completed list.
+ complete_operations_ = this_op->next_;
this_op->next_ = i->second;
i->second = this_op;
return true;
@@ -138,8 +145,8 @@
return false;
}
- // Dispatch all operations corresponding to the descriptor.
- void dispatch_all_operations(Descriptor descriptor,
+ // Perform all operations corresponding to the descriptor.
+ void perform_all_operations(Descriptor descriptor,
const boost::system::error_code& result)
{
typename operation_map::iterator i = operations_.find(descriptor);
@@ -149,14 +156,14 @@
{
op_base* this_op = i->second;
i->second = this_op->next_;
- this_op->next_ = cleanup_operations_;
- cleanup_operations_ = this_op;
- bool done = this_op->invoke(result);
+ this_op->next_ = complete_operations_;
+ complete_operations_ = this_op;
+ bool done = this_op->perform(result);
if (!done)
{
// Operation has not finished yet, so leave at front of queue, and
- // remove from the cleanup list.
- cleanup_operations_ = this_op->next_;
+ // remove from the completed list.
+ complete_operations_ = this_op->next_;
this_op->next_ = i->second;
i->second = this_op;
return;
@@ -179,15 +186,15 @@
if (!descriptors.set(descriptor))
{
boost::system::error_code ec(error::fd_set_failure);
- dispatch_all_operations(descriptor, ec);
+ perform_all_operations(descriptor, ec);
}
}
}
- // Dispatch the operations corresponding to the ready file descriptors
+ // Perform the operations corresponding to the ready file descriptors
// contained in the given descriptor set.
template <typename Descriptor_Set>
- void dispatch_descriptors(const Descriptor_Set& descriptors,
+ void perform_operations_for_descriptors(const Descriptor_Set& descriptors,
const boost::system::error_code& result)
{
typename operation_map::iterator i = operations_.begin();
@@ -198,9 +205,9 @@
{
op_base* this_op = op_iter->second;
op_iter->second = this_op->next_;
- this_op->next_ = cleanup_operations_;
- cleanup_operations_ = this_op;
- bool done = this_op->invoke(result);
+ this_op->next_ = complete_operations_;
+ complete_operations_ = this_op;
+ bool done = this_op->perform(result);
if (done)
{
if (!op_iter->second)
@@ -209,8 +216,8 @@
else
{
// Operation has not finished yet, so leave at front of queue, and
- // remove from the cleanup list.
- cleanup_operations_ = this_op->next_;
+ // remove from the completed list.
+ complete_operations_ = this_op->next_;
this_op->next_ = op_iter->second;
op_iter->second = this_op;
}
@@ -218,28 +225,28 @@
}
}
- // Dispatch any pending cancels for operations.
- void dispatch_cancellations()
+ // Perform any pending cancels for operations.
+ void perform_cancellations()
{
while (cancelled_operations_)
{
op_base* this_op = cancelled_operations_;
cancelled_operations_ = this_op->next_;
- this_op->next_ = cleanup_operations_;
- cleanup_operations_ = this_op;
- this_op->invoke(boost::asio::error::operation_aborted);
+ this_op->next_ = complete_operations_;
+ complete_operations_ = this_op;
+ this_op->perform(boost::asio::error::operation_aborted);
}
}
- // Destroy operations that are waiting to be cleaned up.
- void cleanup_operations()
+ // Complete all operations that are waiting to be completed.
+ void complete_operations()
{
- while (cleanup_operations_)
+ while (complete_operations_)
{
- op_base* next_op = cleanup_operations_->next_;
- cleanup_operations_->next_ = 0;
- cleanup_operations_->destroy();
- cleanup_operations_ = next_op;
+ op_base* next_op = complete_operations_->next_;
+ complete_operations_->next_ = 0;
+ complete_operations_->complete();
+ complete_operations_ = next_op;
}
}
@@ -254,12 +261,12 @@
cancelled_operations_ = next_op;
}
- while (cleanup_operations_)
+ while (complete_operations_)
{
- op_base* next_op = cleanup_operations_->next_;
- cleanup_operations_->next_ = 0;
- cleanup_operations_->destroy();
- cleanup_operations_ = next_op;
+ op_base* next_op = complete_operations_->next_;
+ complete_operations_->next_ = 0;
+ complete_operations_->destroy();
+ complete_operations_ = next_op;
}
typename operation_map::iterator i = operations_.begin();
@@ -291,28 +298,40 @@
}
// Perform the operation.
- bool invoke(const boost::system::error_code& result)
+ bool perform(const boost::system::error_code& result)
+ {
+ result_ = result;
+ return perform_func_(this, result_, bytes_transferred_);
+ }
+
+ // Destroy the operation and post the handler.
+ void complete()
{
- return invoke_func_(this, result);
+ complete_func_(this, result_, bytes_transferred_);
}
// Destroy the operation.
void destroy()
{
- return destroy_func_(this);
+ destroy_func_(this);
}
protected:
- typedef bool (*invoke_func_type)(op_base*,
- const boost::system::error_code&);
+ typedef bool (*perform_func_type)(op_base*,
+ boost::system::error_code&, std::size_t&);
+ typedef void (*complete_func_type)(op_base*,
+ const boost::system::error_code&, std::size_t);
typedef void (*destroy_func_type)(op_base*);
// Construct an operation for the given descriptor.
- op_base(invoke_func_type invoke_func,
+ op_base(perform_func_type perform_func, complete_func_type complete_func,
destroy_func_type destroy_func, Descriptor descriptor)
- : invoke_func_(invoke_func),
+ : perform_func_(perform_func),
+ complete_func_(complete_func),
destroy_func_(destroy_func),
descriptor_(descriptor),
+ result_(),
+ bytes_transferred_(0),
next_(0)
{
}
@@ -325,48 +344,84 @@
private:
friend class reactor_op_queue<Descriptor>;
- // The function to be called to dispatch the handler.
- invoke_func_type invoke_func_;
+ // The function to be called to perform the operation.
+ perform_func_type perform_func_;
+
+ // The function to be called to delete the operation and post the handler.
+ complete_func_type complete_func_;
- // The function to be called to delete the handler.
+ // The function to be called to delete the operation.
destroy_func_type destroy_func_;
// The descriptor associated with the operation.
Descriptor descriptor_;
+ // The result of the operation.
+ boost::system::error_code result_;
+
+ // The number of bytes transferred in the operation.
+ std::size_t bytes_transferred_;
+
// The next operation for the same file descriptor.
op_base* next_;
};
- // Adaptor class template for using handlers in operations.
- template <typename Handler>
+ // Adaptor class template for operations.
+ template <typename Operation>
class op
: public op_base
{
public:
// Constructor.
- op(Descriptor descriptor, Handler handler)
- : op_base(&op<Handler>::invoke_handler,
- &op<Handler>::destroy_handler, descriptor),
- handler_(handler)
+ op(Descriptor descriptor, Operation operation)
+ : op_base(&op<Operation>::do_perform, &op<Operation>::do_complete,
+ &op<Operation>::do_destroy, descriptor),
+ operation_(operation)
{
}
- // Invoke the handler.
- static bool invoke_handler(op_base* base,
- const boost::system::error_code& result)
+ // Perform the operation.
+ static bool do_perform(op_base* base,
+ boost::system::error_code& result, std::size_t& bytes_transferred)
+ {
+ return static_cast<op<Operation>*>(base)->operation_.perform(
+ result, bytes_transferred);
+ }
+
+ // Destroy the operation and post the handler.
+ static void do_complete(op_base* base,
+ const boost::system::error_code& result, std::size_t bytes_transferred)
{
- return static_cast<op<Handler>*>(base)->handler_(result);
+ // Take ownership of the operation object.
+ typedef op<Operation> this_type;
+ this_type* this_op(static_cast<this_type*>(base));
+ typedef handler_alloc_traits<Operation, this_type> alloc_traits;
+ handler_ptr<alloc_traits> ptr(this_op->operation_, this_op);
+
+ // Make a copy of the error_code and the operation so that the memory can
+ // be deallocated before the upcall is made.
+ boost::system::error_code ec(result);
+ Operation operation(this_op->operation_);
+
+ // Free the memory associated with the operation.
+ ptr.reset();
+
+ // Make the upcall.
+ operation.complete(ec, bytes_transferred);
}
- // Delete the handler.
- static void destroy_handler(op_base* base)
+ // Destroy the operation.
+ static void do_destroy(op_base* base)
{
- delete static_cast<op<Handler>*>(base);
+ // Take ownership of the operation object.
+ typedef op<Operation> this_type;
+ this_type* this_op(static_cast<this_type*>(base));
+ typedef handler_alloc_traits<Operation, this_type> alloc_traits;
+ handler_ptr<alloc_traits> ptr(this_op->operation_, this_op);
}
private:
- Handler handler_;
+ Operation operation_;
};
// The type for a map of operations.
@@ -378,8 +433,8 @@
// The list of operations that have been cancelled.
op_base* cancelled_operations_;
- // The list of operations to be destroyed.
- op_base* cleanup_operations_;
+ // The list of operations waiting to be completed.
+ op_base* complete_operations_;
};
} // namespace detail
Modified: trunk/boost/asio/detail/select_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/select_reactor.hpp (original)
+++ trunk/boost/asio/detail/select_reactor.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -171,19 +171,30 @@
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether one of the handlers has already been called. If it has,
// then we don't want to do anything in this handler.
if (*completed_)
+ {
+ completed_.reset(); // Indicate that this handler should not complete.
return true;
+ }
// Cancel the other reactor operation for the connection.
*completed_ = true;
reactor_.enqueue_cancel_ops_unlocked(descriptor_);
// Call the contained handler.
- return handler_(result);
+ return handler_.perform(ec, bytes_transferred);
+ }
+
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ if (completed_.get())
+ handler_.complete(ec, bytes_transferred);
}
private:
@@ -300,16 +311,16 @@
// Dispatch any operation cancellations that were made while the select
// loop was not running.
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
- except_op_queue_.dispatch_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
+ except_op_queue_.perform_cancellations();
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
timer_queues_[i]->dispatch_cancellations();
// Check if the thread is supposed to stop.
if (stop_thread_)
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -318,7 +329,7 @@
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
&& except_op_queue_.empty() && all_timer_queues_are_empty())
{
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
return;
}
@@ -360,15 +371,15 @@
{
// Exception operations must be processed first to ensure that any
// out-of-band data is read before normal data.
- except_op_queue_.dispatch_descriptors(except_fds,
- boost::system::error_code());
- read_op_queue_.dispatch_descriptors(read_fds,
- boost::system::error_code());
- write_op_queue_.dispatch_descriptors(write_fds,
- boost::system::error_code());
- except_op_queue_.dispatch_cancellations();
- read_op_queue_.dispatch_cancellations();
- write_op_queue_.dispatch_cancellations();
+ except_op_queue_.perform_operations_for_descriptors(
+ except_fds, boost::system::error_code());
+ read_op_queue_.perform_operations_for_descriptors(
+ read_fds, boost::system::error_code());
+ write_op_queue_.perform_operations_for_descriptors(
+ write_fds, boost::system::error_code());
+ except_op_queue_.perform_cancellations();
+ read_op_queue_.perform_cancellations();
+ write_op_queue_.perform_cancellations();
}
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
{
@@ -381,7 +392,7 @@
cancel_ops_unlocked(pending_cancellations_[i]);
pending_cancellations_.clear();
- cleanup_operations_and_timers(lock);
+ complete_operations_and_cleanup_timers(lock);
}
// Run the select loop in the thread.
@@ -466,14 +477,14 @@
// destructors may make calls back into this reactor. We make a copy of the
// vector of timer queues since the original may be modified while the lock
// is not held.
- void cleanup_operations_and_timers(
+ void complete_operations_and_cleanup_timers(
boost::asio::detail::mutex::scoped_lock& lock)
{
timer_queues_for_cleanup_ = timer_queues_;
lock.unlock();
- read_op_queue_.cleanup_operations();
- write_op_queue_.cleanup_operations();
- except_op_queue_.cleanup_operations();
+ read_op_queue_.complete_operations();
+ write_op_queue_.complete_operations();
+ except_op_queue_.complete_operations();
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
timer_queues_for_cleanup_[i]->cleanup_timers();
}
Modified: trunk/boost/asio/detail/win_iocp_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_socket_service.hpp (original)
+++ trunk/boost/asio/detail/win_iocp_socket_service.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -885,21 +885,29 @@
}
template <typename Handler>
- class null_buffers_handler
+ class null_buffers_operation
{
public:
- null_buffers_handler(boost::asio::io_service& io_service, Handler handler)
+ null_buffers_operation(boost::asio::io_service& io_service, Handler handler)
: work_(io_service),
handler_(handler)
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code&,
+ std::size_t& bytes_transferred)
{
- work_.get_io_service().post(bind_handler(handler_, result, 0));
+ bytes_transferred = 0;
return true;
}
+ void complete(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ work_.get_io_service().post(bind_handler(
+ handler_, ec, bytes_transferred));
+ }
+
private:
boost::asio::io_service::work work_;
Handler handler_;
@@ -930,7 +938,7 @@
}
reactor->start_write_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -1157,7 +1165,7 @@
}
reactor->start_write_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -1470,12 +1478,12 @@
if (flags & socket_base::message_out_of_band)
{
reactor->start_except_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler));
+ null_buffers_operation<Handler>(this->get_io_service(), handler));
}
else
{
reactor->start_read_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -1743,12 +1751,12 @@
if (flags & socket_base::message_out_of_band)
{
reactor->start_except_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler));
+ null_buffers_operation<Handler>(this->get_io_service(), handler));
}
else
{
reactor->start_read_op(impl.socket_, impl.reactor_data_,
- null_buffers_handler<Handler>(this->get_io_service(), handler),
+ null_buffers_operation<Handler>(this->get_io_service(), handler),
false);
}
}
@@ -2112,10 +2120,10 @@
}
template <typename Handler>
- class connect_handler
+ class connect_operation
{
public:
- connect_handler(socket_type socket, bool user_set_non_blocking,
+ connect_operation(socket_type socket, bool user_set_non_blocking,
boost::asio::io_service& io_service, Handler handler)
: socket_(socket),
user_set_non_blocking_(user_set_non_blocking),
@@ -2125,32 +2133,25 @@
{
}
- bool operator()(const boost::system::error_code& result)
+ bool perform(boost::system::error_code& ec,
+ std::size_t& bytes_transferred)
{
// Check whether the operation was successful.
- if (result)
- {
- io_service_.post(bind_handler(handler_, result));
+ if (ec)
return true;
- }
// Get the error code from the connect operation.
int connect_error = 0;
size_t connect_error_len = sizeof(connect_error);
- boost::system::error_code ec;
if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR,
&connect_error, &connect_error_len, ec) == socket_error_retval)
- {
- io_service_.post(bind_handler(handler_, ec));
return true;
- }
// If connection failed then post the handler with the error code.
if (connect_error)
{
ec = boost::system::error_code(connect_error,
boost::asio::error::get_system_category());
- io_service_.post(bind_handler(handler_, ec));
return true;
}
@@ -2159,18 +2160,19 @@
{
ioctl_arg_type non_blocking = 0;
if (socket_ops::ioctl(socket_, FIONBIO, &non_blocking, ec))
- {
- io_service_.post(bind_handler(handler_, ec));
return true;
- }
}
// Post the result of the successful connection operation.
ec = boost::system::error_code();
- io_service_.post(bind_handler(handler_, ec));
return true;
}
+ void complete(const boost::system::error_code& ec, std::size_t)
+ {
+ io_service_.post(bind_handler(handler_, ec));
+ }
+
private:
socket_type socket_;
bool user_set_non_blocking_;
@@ -2243,7 +2245,7 @@
// until the socket becomes writeable.
boost::shared_ptr<bool> completed(new bool(false));
reactor->start_connect_op(impl.socket_, impl.reactor_data_,
- connect_handler<Handler>(
+ connect_operation<Handler>(
impl.socket_,
(impl.flags_ & implementation_type::user_set_non_blocking) != 0,
this->get_io_service(), handler));
Modified: trunk/boost/asio/detail/wrapped_handler.hpp
==============================================================================
--- trunk/boost/asio/detail/wrapped_handler.hpp (original)
+++ trunk/boost/asio/detail/wrapped_handler.hpp 2008-05-05 02:30:13 EDT (Mon, 05 May 2008)
@@ -128,22 +128,6 @@
Handler handler_;
};
-template <typename Dispatcher, typename Handler>
-inline void* asio_handler_allocate(std::size_t size,
- wrapped_handler<Dispatcher, Handler>* this_handler)
-{
- return boost_asio_handler_alloc_helpers::allocate(
- size, &this_handler->handler_);
-}
-
-template <typename Dispatcher, typename Handler>
-inline void asio_handler_deallocate(void* pointer, std::size_t size,
- wrapped_handler<Dispatcher, Handler>* this_handler)
-{
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, &this_handler->handler_);
-}
-
template <typename Handler, typename Context>
class rewrapped_handler
{
@@ -169,6 +153,22 @@
Context context_;
};
+template <typename Dispatcher, typename Handler>
+inline void* asio_handler_allocate(std::size_t size,
+ wrapped_handler<Dispatcher, Handler>* this_handler)
+{
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, &this_handler->handler_);
+}
+
+template <typename Dispatcher, typename Handler>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ wrapped_handler<Dispatcher, Handler>* this_handler)
+{
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, &this_handler->handler_);
+}
+
template <typename Function, typename Dispatcher, typename Handler>
inline void asio_handler_invoke(const Function& function,
wrapped_handler<Dispatcher, Handler>* this_handler)
@@ -178,6 +178,22 @@
function, this_handler->handler_));
}
+template <typename Handler, typename Context>
+inline void* asio_handler_allocate(std::size_t size,
+ rewrapped_handler<Handler, Context>* this_handler)
+{
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, &this_handler->context_);
+}
+
+template <typename Handler, typename Context>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ rewrapped_handler<Handler, Context>* this_handler)
+{
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, &this_handler->context_);
+}
+
template <typename Function, typename Handler, typename Context>
inline void asio_handler_invoke(const Function& function,
rewrapped_handler<Handler, Context>* this_handler)
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