Remove default candidate from associated_executor and friends.
diff --git a/asio/include/asio/associated_executor.hpp b/asio/include/asio/associated_executor.hpp
index 65e01a3..1219890 100644
--- a/asio/include/asio/associated_executor.hpp
+++ b/asio/include/asio/associated_executor.hpp
@@ -17,8 +17,8 @@
#include "asio/detail/config.hpp"
#include "asio/detail/type_traits.hpp"
+#include "asio/execution_context.hpp"
#include "asio/is_executor.hpp"
-#include "asio/system_executor.hpp"
#include "asio/detail/push_options.hpp"
@@ -75,7 +75,7 @@
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t,e) and with return type @c type.
*/
-template <typename T, typename Executor = system_executor>
+template <typename T, typename Executor>
struct associated_executor
{
/// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
@@ -88,8 +88,7 @@
/// If @c T has a nested type @c executor_type, returns
/// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
- static type get(const T& t,
- const Executor& ex = Executor()) ASIO_NOEXCEPT
+ static type get(const T& t, const Executor& ex) ASIO_NOEXCEPT
{
return detail::associated_executor_impl<T, Executor>::get(t, ex);
}
@@ -97,17 +96,6 @@
/// Helper function to obtain an object's associated executor.
/**
- * @returns <tt>associated_executor<T>::get(t)</tt>
- */
-template <typename T>
-inline typename associated_executor<T>::type
-get_associated_executor(const T& t) ASIO_NOEXCEPT
-{
- return associated_executor<T>::get(t);
-}
-
-/// Helper function to obtain an object's associated executor.
-/**
* @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
*/
template <typename T, typename Executor>
@@ -137,7 +125,7 @@
#if defined(ASIO_HAS_ALIAS_TEMPLATES)
-template <typename T, typename Executor = system_executor>
+template <typename T, typename Executor>
using associated_executor_t = typename associated_executor<T, Executor>::type;
#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
diff --git a/asio/include/asio/detail/completion_handler.hpp b/asio/include/asio/detail/completion_handler.hpp
index ce8e9b7..328feae 100644
--- a/asio/include/asio/detail/completion_handler.hpp
+++ b/asio/include/asio/detail/completion_handler.hpp
@@ -21,6 +21,7 @@
#include "asio/detail/handler_work.hpp"
#include "asio/detail/memory.hpp"
#include "asio/detail/operation.hpp"
+#include "asio/system_executor.hpp"
#include "asio/detail/push_options.hpp"
@@ -37,7 +38,7 @@
: operation(&completion_handler::do_complete),
handler_(ASIO_MOVE_CAST(Handler)(h))
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, system_executor>::start(handler_, system_executor());
}
static void do_complete(void* owner, operation* base,
@@ -47,7 +48,7 @@
// Take ownership of the handler object.
completion_handler* h(static_cast<completion_handler*>(base));
ptr p = { asio::detail::addressof(h->handler_), h, h };
- handler_work<Handler> w(h->handler_);
+ handler_work<Handler, system_executor> w(h->handler_);
ASIO_HANDLER_COMPLETION((*h));
diff --git a/asio/include/asio/detail/dev_poll_reactor.hpp b/asio/include/asio/detail/dev_poll_reactor.hpp
index 0d62153..6f89d49 100644
--- a/asio/include/asio/detail/dev_poll_reactor.hpp
+++ b/asio/include/asio/detail/dev_poll_reactor.hpp
@@ -84,10 +84,7 @@
per_descriptor_data& source_descriptor_data);
// Post a reactor operation for immediate completion.
- void post_immediate_completion(reactor_op* op, bool is_continuation)
- {
- scheduler_.post_immediate_completion(op, is_continuation);
- }
+ void post_immediate_completion(reactor_op* op, bool is_continuation);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
diff --git a/asio/include/asio/detail/epoll_reactor.hpp b/asio/include/asio/detail/epoll_reactor.hpp
index 032fc85..79b2971 100644
--- a/asio/include/asio/detail/epoll_reactor.hpp
+++ b/asio/include/asio/detail/epoll_reactor.hpp
@@ -114,10 +114,7 @@
per_descriptor_data& source_descriptor_data);
// Post a reactor operation for immediate completion.
- void post_immediate_completion(reactor_op* op, bool is_continuation)
- {
- scheduler_.post_immediate_completion(op, is_continuation);
- }
+ void post_immediate_completion(reactor_op* op, bool is_continuation);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
diff --git a/asio/include/asio/detail/handler_work.hpp b/asio/include/asio/detail/handler_work.hpp
index 9be218c..bd514c2 100644
--- a/asio/include/asio/detail/handler_work.hpp
+++ b/asio/include/asio/detail/handler_work.hpp
@@ -18,6 +18,7 @@
#include "asio/detail/config.hpp"
#include "asio/associated_executor.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
+#include "asio/system_executor.hpp"
#include "asio/detail/push_options.hpp"
@@ -28,7 +29,7 @@
// through either the new executors framework or the old invocaton hook. The
// primary template uses the new executors framework.
template <typename Handler,
- typename IoExecutor = system_executor, typename HandlerExecutor
+ typename IoExecutor, typename HandlerExecutor
= typename associated_executor<Handler, IoExecutor>::type>
class handler_work
{
@@ -45,12 +46,6 @@
{
}
- static void start(Handler& handler) ASIO_NOEXCEPT
- {
- HandlerExecutor ex(asio::get_associated_executor(handler));
- ex.on_work_started();
- }
-
static void start(Handler& handler,
const IoExecutor& io_ex) ASIO_NOEXCEPT
{
@@ -90,7 +85,7 @@
{
public:
explicit handler_work(Handler&) ASIO_NOEXCEPT {}
- static void start(Handler&) ASIO_NOEXCEPT {}
+ static void start(Handler&, const system_executor&) ASIO_NOEXCEPT {}
~handler_work() {}
template <typename Function>
diff --git a/asio/include/asio/detail/impl/dev_poll_reactor.hpp b/asio/include/asio/detail/impl/dev_poll_reactor.hpp
index 31cd719..107a9eb 100644
--- a/asio/include/asio/detail/impl/dev_poll_reactor.hpp
+++ b/asio/include/asio/detail/impl/dev_poll_reactor.hpp
@@ -19,11 +19,19 @@
#if defined(ASIO_HAS_DEV_POLL)
+#include "asio/detail/scheduler.hpp"
+
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
+inline void dev_poll_reactor::post_immediate_completion(
+ reactor_op* op, bool is_continuation)
+{
+ scheduler_.post_immediate_completion(op, is_continuation);
+}
+
template <typename Time_Traits>
void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
{
diff --git a/asio/include/asio/detail/impl/epoll_reactor.hpp b/asio/include/asio/detail/impl/epoll_reactor.hpp
index 42d52a7..fe40528 100644
--- a/asio/include/asio/detail/impl/epoll_reactor.hpp
+++ b/asio/include/asio/detail/impl/epoll_reactor.hpp
@@ -17,11 +17,19 @@
#if defined(ASIO_HAS_EPOLL)
+#include "asio/detail/scheduler.hpp"
+
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
+inline void epoll_reactor::post_immediate_completion(
+ reactor_op* op, bool is_continuation)
+{
+ scheduler_.post_immediate_completion(op, is_continuation);
+}
+
template <typename Time_Traits>
void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
{
diff --git a/asio/include/asio/detail/impl/kqueue_reactor.hpp b/asio/include/asio/detail/impl/kqueue_reactor.hpp
index 6897dc2..43798c0 100644
--- a/asio/include/asio/detail/impl/kqueue_reactor.hpp
+++ b/asio/include/asio/detail/impl/kqueue_reactor.hpp
@@ -20,11 +20,19 @@
#if defined(ASIO_HAS_KQUEUE)
+#include "asio/detail/scheduler.hpp"
+
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
+inline void kqueue_reactor::post_immediate_completion(
+ reactor_op* op, bool is_continuation)
+{
+ scheduler_.post_immediate_completion(op, is_continuation);
+}
+
template <typename Time_Traits>
void kqueue_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
{
diff --git a/asio/include/asio/detail/impl/select_reactor.hpp b/asio/include/asio/detail/impl/select_reactor.hpp
index dd4418f..eb855bd 100644
--- a/asio/include/asio/detail/impl/select_reactor.hpp
+++ b/asio/include/asio/detail/impl/select_reactor.hpp
@@ -23,11 +23,19 @@
&& !defined(ASIO_HAS_KQUEUE) \
&& !defined(ASIO_WINDOWS_RUNTIME))
+#include "asio/detail/scheduler.hpp"
+
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
+inline void select_reactor::post_immediate_completion(
+ reactor_op* op, bool is_continuation)
+{
+ scheduler_.post_immediate_completion(op, is_continuation);
+}
+
template <typename Time_Traits>
void select_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
{
diff --git a/asio/include/asio/detail/kqueue_reactor.hpp b/asio/include/asio/detail/kqueue_reactor.hpp
index 38ae067..664a42b 100644
--- a/asio/include/asio/detail/kqueue_reactor.hpp
+++ b/asio/include/asio/detail/kqueue_reactor.hpp
@@ -24,8 +24,8 @@
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
+#include "asio/detail/conditionally_enabled_mutex.hpp"
#include "asio/detail/limits.hpp"
-#include "asio/detail/mutex.hpp"
#include "asio/detail/object_pool.hpp"
#include "asio/detail/op_queue.hpp"
#include "asio/detail/reactor_op.hpp"
@@ -114,10 +114,7 @@
per_descriptor_data& source_descriptor_data);
// Post a reactor operation for immediate completion.
- void post_immediate_completion(reactor_op* op, bool is_continuation)
- {
- scheduler_.post_immediate_completion(op, is_continuation);
- }
+ void post_immediate_completion(reactor_op* op, bool is_continuation);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
diff --git a/asio/include/asio/detail/select_reactor.hpp b/asio/include/asio/detail/select_reactor.hpp
index 01eb716..96889b0 100644
--- a/asio/include/asio/detail/select_reactor.hpp
+++ b/asio/include/asio/detail/select_reactor.hpp
@@ -90,10 +90,7 @@
per_descriptor_data& descriptor_data, reactor_op* op);
// Post a reactor operation for immediate completion.
- void post_immediate_completion(reactor_op* op, bool is_continuation)
- {
- scheduler_.post_immediate_completion(op, is_continuation);
- }
+ void post_immediate_completion(reactor_op* op, bool is_continuation);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
diff --git a/asio/include/asio/detail/work_dispatcher.hpp b/asio/include/asio/detail/work_dispatcher.hpp
index bcaf53e..6b53974 100644
--- a/asio/include/asio/detail/work_dispatcher.hpp
+++ b/asio/include/asio/detail/work_dispatcher.hpp
@@ -16,37 +16,37 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
-#include "asio/associated_executor.hpp"
#include "asio/associated_allocator.hpp"
#include "asio/executor_work_guard.hpp"
+#include "asio/is_executor.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename Executor>
class work_dispatcher
{
public:
template <typename CompletionHandler>
- explicit work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler)
- : work_((get_associated_executor)(handler)),
- handler_(ASIO_MOVE_CAST(CompletionHandler)(handler))
+ work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,
+ const Executor& handler_ex)
+ : handler_(ASIO_MOVE_CAST(CompletionHandler)(handler)),
+ work_(handler_ex)
{
}
#if defined(ASIO_HAS_MOVE)
work_dispatcher(const work_dispatcher& other)
- : work_(other.work_),
- handler_(other.handler_)
+ : handler_(other.handler_),
+ work_(other.work_)
{
}
work_dispatcher(work_dispatcher&& other)
- : work_(ASIO_MOVE_CAST(executor_work_guard<
- typename associated_executor<Handler>::type>)(other.work_)),
- handler_(ASIO_MOVE_CAST(Handler)(other.handler_))
+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),
+ work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_))
{
}
#endif // defined(ASIO_HAS_MOVE)
@@ -61,8 +61,8 @@
}
private:
- executor_work_guard<typename associated_executor<Handler>::type> work_;
Handler handler_;
+ executor_work_guard<Executor> work_;
};
} // namespace detail
diff --git a/asio/include/asio/executor_work_guard.hpp b/asio/include/asio/executor_work_guard.hpp
index 6fcb491..e2c903f 100644
--- a/asio/include/asio/executor_work_guard.hpp
+++ b/asio/include/asio/executor_work_guard.hpp
@@ -128,17 +128,6 @@
}
/// Create an @ref executor_work_guard object.
-template <typename T>
-inline executor_work_guard<typename associated_executor<T>::type>
-make_work_guard(const T& t,
- typename enable_if<!is_executor<T>::value &&
- !is_convertible<T&, execution_context&>::value>::type* = 0)
-{
- return executor_work_guard<typename associated_executor<T>::type>(
- associated_executor<T>::get(t));
-}
-
-/// Create an @ref executor_work_guard object.
template <typename T, typename Executor>
inline executor_work_guard<typename associated_executor<T, Executor>::type>
make_work_guard(const T& t, const Executor& ex,
diff --git a/asio/include/asio/impl/defer.hpp b/asio/include/asio/impl/defer.hpp
index 5346731..eaae6fe 100644
--- a/asio/include/asio/impl/defer.hpp
+++ b/asio/include/asio/impl/defer.hpp
@@ -31,15 +31,39 @@
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
- typedef typename decay<CompletionHandler>::type DecayedHandler;
+ typedef typename decay<CompletionHandler>::type handler_t;
- typename associated_executor<DecayedHandler>::type ex(
- (get_associated_executor)(handler));
+ typedef typename handler_t::executor_type io_ex_t;
+ io_ex_t io_ex(handler.get_executor());
- typename associated_allocator<DecayedHandler>::type alloc(
+ typedef typename associated_executor<handler_t, io_ex_t>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, io_ex));
+
+ typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
- ex.defer(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ if (this->is_same_executor(io_ex, handler_ex))
+ {
+ io_ex.defer(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
+ else
+ {
+ io_ex.defer(detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex), alloc);
+ }
+ }
+
+private:
+ template <typename T, typename U>
+ bool is_same_executor(const T&, const U&) const
+ {
+ return false;
+ }
+
+ template <typename T>
+ bool is_same_executor(const T& a, const T& b) const
+ {
+ return a == b;
}
};
@@ -50,29 +74,52 @@
typedef Executor executor_type;
explicit initiate_defer_with_executor(const Executor& ex)
- : ex_(ex)
+ : io_ex_(ex)
{
}
executor_type get_executor() const ASIO_NOEXCEPT
{
- return ex_;
+ return io_ex_;
}
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
- typedef typename decay<CompletionHandler>::type DecayedHandler;
+ typedef typename decay<CompletionHandler>::type handler_t;
- typename associated_allocator<DecayedHandler>::type alloc(
+ typedef typename associated_executor<
+ handler_t, Executor>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, io_ex_));
+
+ typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
- ex_.defer(detail::work_dispatcher<DecayedHandler>(
- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ if (this->is_same_executor(io_ex_, handler_ex))
+ {
+ io_ex_.defer(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
+ else
+ {
+ io_ex_.defer(detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex), alloc);
+ }
}
private:
- Executor ex_;
+ template <typename T, typename U>
+ bool is_same_executor(const T&, const U&) const
+ {
+ return false;
+ }
+
+ template <typename T>
+ bool is_same_executor(const T& a, const T& b) const
+ {
+ return a == b;
+ }
+
+ Executor io_ex_;
};
} // namespace detail
diff --git a/asio/include/asio/impl/dispatch.hpp b/asio/include/asio/impl/dispatch.hpp
index 0b7740b..8b27236 100644
--- a/asio/include/asio/impl/dispatch.hpp
+++ b/asio/include/asio/impl/dispatch.hpp
@@ -31,15 +31,39 @@
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
- typedef typename decay<CompletionHandler>::type DecayedHandler;
+ typedef typename decay<CompletionHandler>::type handler_t;
- typename associated_executor<DecayedHandler>::type ex(
- (get_associated_executor)(handler));
+ typedef typename handler_t::executor_type io_ex_t;
+ io_ex_t io_ex(handler.get_executor());
- typename associated_allocator<DecayedHandler>::type alloc(
+ typedef typename associated_executor<handler_t, io_ex_t>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, io_ex));
+
+ typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
- ex.dispatch(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ if (this->is_same_executor(io_ex, handler_ex))
+ {
+ io_ex.dispatch(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
+ else
+ {
+ io_ex.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex), alloc);
+ }
+ }
+
+private:
+ template <typename T, typename U>
+ bool is_same_executor(const T&, const U&) const
+ {
+ return false;
+ }
+
+ template <typename T>
+ bool is_same_executor(const T& a, const T& b) const
+ {
+ return a == b;
}
};
@@ -50,29 +74,52 @@
typedef Executor executor_type;
explicit initiate_dispatch_with_executor(const Executor& ex)
- : ex_(ex)
+ : io_ex_(ex)
{
}
executor_type get_executor() const ASIO_NOEXCEPT
{
- return ex_;
+ return io_ex_;
}
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
- typedef typename decay<CompletionHandler>::type DecayedHandler;
+ typedef typename decay<CompletionHandler>::type handler_t;
- typename associated_allocator<DecayedHandler>::type alloc(
+ typedef typename associated_executor<
+ handler_t, Executor>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, io_ex_));
+
+ typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
- ex_.dispatch(detail::work_dispatcher<DecayedHandler>(
- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ if (this->is_same_executor(io_ex_, handler_ex))
+ {
+ io_ex_.dispatch(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
+ else
+ {
+ io_ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex), alloc);
+ }
}
private:
- Executor ex_;
+ template <typename T, typename U>
+ bool is_same_executor(const T&, const U&) const
+ {
+ return false;
+ }
+
+ template <typename T>
+ bool is_same_executor(const T& a, const T& b) const
+ {
+ return a == b;
+ }
+
+ Executor io_ex_;
};
} // namespace detail
diff --git a/asio/include/asio/impl/post.hpp b/asio/include/asio/impl/post.hpp
index 7d01482..2edc933 100644
--- a/asio/include/asio/impl/post.hpp
+++ b/asio/include/asio/impl/post.hpp
@@ -31,15 +31,39 @@
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
- typedef typename decay<CompletionHandler>::type DecayedHandler;
+ typedef typename decay<CompletionHandler>::type handler_t;
- typename associated_executor<DecayedHandler>::type ex(
- (get_associated_executor)(handler));
+ typedef typename handler_t::executor_type io_ex_t;
+ io_ex_t io_ex(handler.get_executor());
- typename associated_allocator<DecayedHandler>::type alloc(
+ typedef typename associated_executor<handler_t, io_ex_t>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, io_ex));
+
+ typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
- ex.post(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ if (this->is_same_executor(io_ex, handler_ex))
+ {
+ io_ex.post(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
+ else
+ {
+ io_ex.post(detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex), alloc);
+ }
+ }
+
+private:
+ template <typename T, typename U>
+ bool is_same_executor(const T&, const U&) const
+ {
+ return false;
+ }
+
+ template <typename T>
+ bool is_same_executor(const T& a, const T& b) const
+ {
+ return a == b;
}
};
@@ -50,29 +74,52 @@
typedef Executor executor_type;
explicit initiate_post_with_executor(const Executor& ex)
- : ex_(ex)
+ : io_ex_(ex)
{
}
executor_type get_executor() const ASIO_NOEXCEPT
{
- return ex_;
+ return io_ex_;
}
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
- typedef typename decay<CompletionHandler>::type DecayedHandler;
+ typedef typename decay<CompletionHandler>::type handler_t;
- typename associated_allocator<DecayedHandler>::type alloc(
+ typedef typename associated_executor<
+ handler_t, Executor>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, io_ex_));
+
+ typename associated_allocator<handler_t>::type alloc(
(get_associated_allocator)(handler));
- ex_.post(detail::work_dispatcher<DecayedHandler>(
- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ if (this->is_same_executor(io_ex_, handler_ex))
+ {
+ io_ex_.post(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
+ else
+ {
+ io_ex_.post(detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex), alloc);
+ }
}
private:
- Executor ex_;
+ template <typename T, typename U>
+ bool is_same_executor(const T&, const U&) const
+ {
+ return false;
+ }
+
+ template <typename T>
+ bool is_same_executor(const T& a, const T& b) const
+ {
+ return a == b;
+ }
+
+ Executor io_ex_;
};
} // namespace detail
diff --git a/asio/src/examples/cpp14/executors/async_1.cpp b/asio/src/examples/cpp14/executors/async_1.cpp
index d282b74..c63c421 100644
--- a/asio/src/examples/cpp14/executors/async_1.cpp
+++ b/asio/src/examples/cpp14/executors/async_1.cpp
@@ -1,4 +1,5 @@
#include <asio/ts/executor.hpp>
+#include <asio/system_executor.hpp>
#include <asio/thread_pool.hpp>
#include <iostream>
#include <string>
@@ -7,6 +8,7 @@
using asio::dispatch;
using asio::make_work_guard;
using asio::post;
+using asio::system_executor;
using asio::thread_pool;
// A function to asynchronously read a single line from an input stream.
@@ -14,10 +16,11 @@
void async_getline(std::istream& is, Handler handler)
{
// Create executor_work for the handler's associated executor.
- auto work = make_work_guard(handler);
+ auto work = make_work_guard(handler, system_executor());
// Post a function object to do the work asynchronously.
- post([&is, work, handler=std::move(handler)]() mutable
+ post(system_executor(),
+ [&is, work, handler=std::move(handler)]() mutable
{
std::string line;
std::getline(is, line);
diff --git a/asio/src/examples/cpp14/executors/async_2.cpp b/asio/src/examples/cpp14/executors/async_2.cpp
index b39156d..4e9e99a 100644
--- a/asio/src/examples/cpp14/executors/async_2.cpp
+++ b/asio/src/examples/cpp14/executors/async_2.cpp
@@ -8,6 +8,7 @@
using asio::get_associated_executor;
using asio::make_work_guard;
using asio::post;
+using asio::system_executor;
using asio::thread_pool;
// A function to asynchronously read a single line from an input stream.
@@ -15,10 +16,11 @@
void async_getline(std::istream& is, Handler handler)
{
// Create executor_work for the handler's associated executor.
- auto work = make_work_guard(handler);
+ auto work = make_work_guard(handler, system_executor());
// Post a function object to do the work asynchronously.
- post([&is, work, handler=std::move(handler)]() mutable
+ post(system_executor(),
+ [&is, work, handler=std::move(handler)]() mutable
{
std::string line;
std::getline(is, line);
@@ -37,7 +39,7 @@
void async_getlines(std::istream& is, std::string init, Handler handler)
{
// Get the final handler's associated executor.
- auto ex = get_associated_executor(handler);
+ auto ex = get_associated_executor(handler, system_executor());
// Use the associated executor for each operation in the composition.
async_getline(is,
diff --git a/asio/src/tests/unit/archetypes/async_ops.hpp b/asio/src/tests/unit/archetypes/async_ops.hpp
index d3ba7d8..8752482 100644
--- a/asio/src/tests/unit/archetypes/async_ops.hpp
+++ b/asio/src/tests/unit/archetypes/async_ops.hpp
@@ -15,6 +15,7 @@
#include <asio/associated_executor.hpp>
#include <asio/async_result.hpp>
#include <asio/error.hpp>
+#include <asio/system_executor.hpp>
#if defined(ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
@@ -43,8 +44,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
ex.post(ASIO_MOVE_CAST(handler_type)(completion.completion_handler), a);
@@ -64,8 +65,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{
@@ -98,8 +99,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{
@@ -132,8 +133,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
ex.post(
bindns::bind(
@@ -158,8 +159,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{
@@ -194,8 +195,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{
@@ -228,8 +229,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
ex.post(
bindns::bind(
@@ -254,8 +255,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{
@@ -291,8 +292,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{
@@ -325,8 +326,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
ex.post(
bindns::bind(
@@ -351,8 +352,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{
@@ -388,8 +389,8 @@
typename asio::associated_allocator<handler_type>::type a
= asio::get_associated_allocator(completion.completion_handler);
- typename asio::associated_executor<handler_type>::type ex
- = asio::get_associated_executor(completion.completion_handler);
+ typename asio::associated_executor<handler_type, asio::system_executor>::type ex
+ = asio::get_associated_executor(completion.completion_handler, asio::system_executor());
if (ok)
{