1 // 2 // detail/handler_work.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2016 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_HANDLER_WORK_HPP 12 #define ASIO_DETAIL_HANDLER_WORK_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/associated_executor.hpp" 20 #include "asio/detail/handler_invoke_helpers.hpp" 21 22 #include "asio/detail/push_options.hpp" 23 24 namespace asio { 25 namespace detail { 26 27 // A helper class template to allow completion handlers to be dispatched 28 // through either the new executors framework or the old invocaton hook. The 29 // primary template uses the new executors framework. 30 template <typename Handler, typename Executor 31 = typename associated_executor<Handler>::type> 32 class handler_work 33 { 34 public: handler_work(Handler & handler)35 explicit handler_work(Handler& handler) ASIO_NOEXCEPT 36 : executor_(associated_executor<Handler>::get(handler)) 37 { 38 } 39 start(Handler & handler)40 static void start(Handler& handler) ASIO_NOEXCEPT 41 { 42 Executor ex(associated_executor<Handler>::get(handler)); 43 ex.on_work_started(); 44 } 45 ~handler_work()46 ~handler_work() 47 { 48 executor_.on_work_finished(); 49 } 50 51 template <typename Function> complete(Function & function,Handler & handler)52 void complete(Function& function, Handler& handler) 53 { 54 executor_.dispatch(ASIO_MOVE_CAST(Function)(function), 55 associated_allocator<Handler>::get(handler)); 56 } 57 58 private: 59 // Disallow copying and assignment. 60 handler_work(const handler_work&); 61 handler_work& operator=(const handler_work&); 62 63 typename associated_executor<Handler>::type executor_; 64 }; 65 66 // This specialisation dispatches a handler through the old invocation hook. 67 // The specialisation is not strictly required for correctness, as the 68 // system_executor will dispatch through the hook anyway. However, by doing 69 // this we avoid an extra copy of the handler. 70 template <typename Handler> 71 class handler_work<Handler, system_executor> 72 { 73 public: handler_work(Handler &)74 explicit handler_work(Handler&) ASIO_NOEXCEPT {} start(Handler &)75 static void start(Handler&) ASIO_NOEXCEPT {} ~handler_work()76 ~handler_work() {} 77 78 template <typename Function> complete(Function & function,Handler & handler)79 void complete(Function& function, Handler& handler) 80 { 81 asio_handler_invoke_helpers::invoke(function, handler); 82 } 83 84 private: 85 // Disallow copying and assignment. 86 handler_work(const handler_work&); 87 handler_work& operator=(const handler_work&); 88 }; 89 90 } // namespace detail 91 } // namespace asio 92 93 #include "asio/detail/pop_options.hpp" 94 95 #endif // ASIO_DETAIL_HANDLER_WORK_HPP 96