Clementine
work_dispatcher.hpp
1 //
2 // detail/work_dispatcher.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_DETAIL_WORK_DISPATCHER_HPP
12 #define ASIO_DETAIL_WORK_DISPATCHER_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include "asio/detail/type_traits.hpp"
20 #include "asio/associated_executor.hpp"
21 #include "asio/associated_allocator.hpp"
22 #include "asio/executor_work_guard.hpp"
23 #include "asio/execution/executor.hpp"
24 #include "asio/execution/allocator.hpp"
25 #include "asio/execution/blocking.hpp"
26 #include "asio/execution/outstanding_work.hpp"
27 #include "asio/prefer.hpp"
28 
29 #include "asio/detail/push_options.hpp"
30 
31 namespace asio {
32 namespace detail {
33 
34 template <typename Handler, typename Executor, typename = void>
35 struct is_work_dispatcher_required : true_type
36 {
37 };
38 
39 template <typename Handler, typename Executor>
40 struct is_work_dispatcher_required<Handler, Executor,
41  typename enable_if<
42  is_same<
43  typename associated_executor<Handler,
44  Executor>::asio_associated_executor_is_unspecialised,
45  void
46  >::value
47  >::type> : false_type
48 {
49 };
50 
51 template <typename Handler, typename Executor, typename = void>
53 {
54 public:
55  template <typename CompletionHandler>
56  work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,
57  const Executor& handler_ex)
58  : handler_(ASIO_MOVE_CAST(CompletionHandler)(handler)),
59  executor_(asio::prefer(handler_ex,
60  execution::outstanding_work.tracked))
61  {
62  }
63 
64 #if defined(ASIO_HAS_MOVE)
65  work_dispatcher(const work_dispatcher& other)
66  : handler_(other.handler_),
67  executor_(other.executor_)
68  {
69  }
70 
72  : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),
73  executor_(ASIO_MOVE_CAST(work_executor_type)(other.executor_))
74  {
75  }
76 #endif // defined(ASIO_HAS_MOVE)
77 
78  void operator()()
79  {
80  execution::execute(
81  asio::prefer(executor_,
82  execution::blocking.possibly,
83  execution::allocator((get_associated_allocator)(handler_))),
84  ASIO_MOVE_CAST(Handler)(handler_));
85  }
86 
87 private:
88  typedef typename decay<
89  typename prefer_result<const Executor&,
91  >::type
92  >::type work_executor_type;
93 
94  Handler handler_;
95  work_executor_type executor_;
96 };
97 
98 #if !defined(ASIO_NO_TS_EXECUTORS)
99 
100 template <typename Handler, typename Executor>
101 class work_dispatcher<Handler, Executor,
102  typename enable_if<!execution::is_executor<Executor>::value>::type>
103 {
104 public:
105  template <typename CompletionHandler>
106  work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,
107  const Executor& handler_ex)
108  : work_(handler_ex),
109  handler_(ASIO_MOVE_CAST(CompletionHandler)(handler))
110  {
111  }
112 
113 #if defined(ASIO_HAS_MOVE)
114  work_dispatcher(const work_dispatcher& other)
115  : work_(other.work_),
116  handler_(other.handler_)
117  {
118  }
119 
121  : work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_)),
122  handler_(ASIO_MOVE_CAST(Handler)(other.handler_))
123  {
124  }
125 #endif // defined(ASIO_HAS_MOVE)
126 
127  void operator()()
128  {
130  (get_associated_allocator)(handler_));
131  work_.get_executor().dispatch(
132  ASIO_MOVE_CAST(Handler)(handler_), alloc);
133  work_.reset();
134  }
135 
136 private:
138  Handler handler_;
139 };
140 
141 #endif // !defined(ASIO_NO_TS_EXECUTORS)
142 
143 } // namespace detail
144 } // namespace asio
145 
146 #include "asio/detail/pop_options.hpp"
147 
148 #endif // ASIO_DETAIL_WORK_DISPATCHER_HPP
Definition: work_dispatcher.hpp:35
Definition: work_dispatcher.hpp:52
Definition: chrono.h:284
Definition: is_executor.hpp:114
Definition: type_traits.hpp:97
Definition: outstanding_work.hpp:153
Traits type used to obtain the executor associated with an object.
Definition: associated_executor.hpp:76
Definition: prefer.hpp:623
Definition: handler_work.hpp:37
detail::associated_allocator_impl< T, Allocator >::type type
If T has a nested type allocator_type, T::allocator_type.
Definition: associated_allocator.hpp:79
Definition: any_io_executor.hpp:28