1 // 2 // detail/task_io_service.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2011 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 BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP 12 #define BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 20 #if !defined(BOOST_ASIO_HAS_IOCP) 21 22 #include <boost/system/error_code.hpp> 23 #include <boost/asio/io_service.hpp> 24 #include <boost/asio/detail/atomic_count.hpp> 25 #include <boost/asio/detail/mutex.hpp> 26 #include <boost/asio/detail/op_queue.hpp> 27 #include <boost/asio/detail/reactor_fwd.hpp> 28 #include <boost/asio/detail/task_io_service_fwd.hpp> 29 #include <boost/asio/detail/task_io_service_operation.hpp> 30 31 #include <boost/asio/detail/push_options.hpp> 32 33 namespace boost { 34 namespace asio { 35 namespace detail { 36 37 class task_io_service 38 : public boost::asio::detail::service_base<task_io_service> 39 { 40 public: 41 typedef task_io_service_operation operation; 42 43 // Constructor. 44 BOOST_ASIO_DECL task_io_service(boost::asio::io_service& io_service); 45 46 // How many concurrent threads are likely to run the io_service. 47 BOOST_ASIO_DECL void init(std::size_t concurrency_hint); 48 49 // Destroy all user-defined handler objects owned by the service. 50 BOOST_ASIO_DECL void shutdown_service(); 51 52 // Initialise the task, if required. 53 BOOST_ASIO_DECL void init_task(); 54 55 // Run the event loop until interrupted or no more work. 56 BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec); 57 58 // Run until interrupted or one operation is performed. 59 BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec); 60 61 // Poll for operations without blocking. 62 BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec); 63 64 // Poll for one operation without blocking. 65 BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec); 66 67 // Interrupt the event processing loop. 68 BOOST_ASIO_DECL void stop(); 69 70 // Determine whether the io_service is stopped. 71 BOOST_ASIO_DECL bool stopped() const; 72 73 // Reset in preparation for a subsequent run invocation. 74 BOOST_ASIO_DECL void reset(); 75 76 // Notify that some work has started. work_started()77 void work_started() 78 { 79 ++outstanding_work_; 80 } 81 82 // Notify that some work has finished. work_finished()83 void work_finished() 84 { 85 if (--outstanding_work_ == 0) 86 stop(); 87 } 88 89 // Request invocation of the given handler. 90 template <typename Handler> 91 void dispatch(Handler handler); 92 93 // Request invocation of the given handler and return immediately. 94 template <typename Handler> 95 void post(Handler handler); 96 97 // Request invocation of the given operation and return immediately. Assumes 98 // that work_started() has not yet been called for the operation. 99 BOOST_ASIO_DECL void post_immediate_completion(operation* op); 100 101 // Request invocation of the given operation and return immediately. Assumes 102 // that work_started() was previously called for the operation. 103 BOOST_ASIO_DECL void post_deferred_completion(operation* op); 104 105 // Request invocation of the given operations and return immediately. Assumes 106 // that work_started() was previously called for each operation. 107 BOOST_ASIO_DECL void post_deferred_completions(op_queue<operation>& ops); 108 109 // Process unfinished operations as part of a shutdown_service operation. 110 // Assumes that work_started() was previously called for the operations. 111 BOOST_ASIO_DECL void abandon_operations(op_queue<operation>& ops); 112 113 private: 114 // Structure containing information about an idle thread. 115 struct idle_thread_info; 116 117 // Run at most one operation. Blocks only if this_idle_thread is non-null. 118 BOOST_ASIO_DECL std::size_t do_one(mutex::scoped_lock& lock, 119 idle_thread_info* this_idle_thread); 120 121 // Stop the task and all idle threads. 122 BOOST_ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock); 123 124 // Wakes a single idle thread and unlocks the mutex. Returns true if an idle 125 // thread was found. If there is no idle thread, returns false and leaves the 126 // mutex locked. 127 BOOST_ASIO_DECL bool wake_one_idle_thread_and_unlock( 128 mutex::scoped_lock& lock); 129 130 // Wake a single idle thread, or the task, and always unlock the mutex. 131 BOOST_ASIO_DECL void wake_one_thread_and_unlock( 132 mutex::scoped_lock& lock); 133 134 // Helper class to perform task-related operations on block exit. 135 struct task_cleanup; 136 friend struct task_cleanup; 137 138 // Helper class to call work_finished() on block exit. 139 struct work_finished_on_block_exit; 140 141 // Mutex to protect access to internal data. 142 mutable mutex mutex_; 143 144 // The task to be run by this service. 145 reactor* task_; 146 147 // Operation object to represent the position of the task in the queue. 148 struct task_operation : operation 149 { task_operationboost::asio::detail::task_io_service::task_operation150 task_operation() : operation(0) {} 151 } task_operation_; 152 153 // Whether the task has been interrupted. 154 bool task_interrupted_; 155 156 // The count of unfinished work. 157 atomic_count outstanding_work_; 158 159 // The queue of handlers that are ready to be delivered. 160 op_queue<operation> op_queue_; 161 162 // Flag to indicate that the dispatcher has been stopped. 163 bool stopped_; 164 165 // Flag to indicate that the dispatcher has been shut down. 166 bool shutdown_; 167 168 // The threads that are currently idle. 169 idle_thread_info* first_idle_thread_; 170 }; 171 172 } // namespace detail 173 } // namespace asio 174 } // namespace boost 175 176 #include <boost/asio/detail/pop_options.hpp> 177 178 #include <boost/asio/detail/impl/task_io_service.hpp> 179 #if defined(BOOST_ASIO_HEADER_ONLY) 180 # include <boost/asio/detail/impl/task_io_service.ipp> 181 #endif // defined(BOOST_ASIO_HEADER_ONLY) 182 183 #endif // !defined(BOOST_ASIO_HAS_IOCP) 184 185 #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP 186