2 // detail/scheduler.hpp
3 // ~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_DETAIL_SCHEDULER_HPP
12 #define BOOST_ASIO_DETAIL_SCHEDULER_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #include <boost/system/error_code.hpp>
21 #include <boost/asio/execution_context.hpp>
22 #include <boost/asio/detail/atomic_count.hpp>
23 #include <boost/asio/detail/conditionally_enabled_event.hpp>
24 #include <boost/asio/detail/conditionally_enabled_mutex.hpp>
25 #include <boost/asio/detail/op_queue.hpp>
26 #include <boost/asio/detail/reactor_fwd.hpp>
27 #include <boost/asio/detail/scheduler_operation.hpp>
28 #include <boost/asio/detail/thread_context.hpp>
30 #include <boost/asio/detail/push_options.hpp>
36 struct scheduler_thread_info;
39 : public execution_context_service_base<scheduler>,
43 typedef scheduler_operation operation;
45 // Constructor. Specifies the number of concurrent threads that are likely to
46 // run the scheduler. If set to 1 certain optimisation are performed.
47 BOOST_ASIO_DECL scheduler(boost::asio::execution_context& ctx,
48 int concurrency_hint = 0);
50 // Destroy all user-defined handler objects owned by the service.
51 BOOST_ASIO_DECL void shutdown();
53 // Initialise the task, if required.
54 BOOST_ASIO_DECL void init_task();
56 // Run the event loop until interrupted or no more work.
57 BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec);
59 // Run until interrupted or one operation is performed.
60 BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec);
62 // Run until timeout, interrupted, or one operation is performed.
63 BOOST_ASIO_DECL std::size_t wait_one(
64 long usec, boost::system::error_code& ec);
66 // Poll for operations without blocking.
67 BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec);
69 // Poll for one operation without blocking.
70 BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec);
72 // Interrupt the event processing loop.
73 BOOST_ASIO_DECL void stop();
75 // Determine whether the scheduler is stopped.
76 BOOST_ASIO_DECL bool stopped() const;
78 // Restart in preparation for a subsequent run invocation.
79 BOOST_ASIO_DECL void restart();
81 // Notify that some work has started.
87 // Used to compensate for a forthcoming work_finished call. Must be called
88 // from within a scheduler-owned thread.
89 BOOST_ASIO_DECL void compensating_work_started();
91 // Notify that some work has finished.
94 if (--outstanding_work_ == 0)
98 // Return whether a handler can be dispatched immediately.
101 return thread_call_stack::contains(this) != 0;
104 // Request invocation of the given operation and return immediately. Assumes
105 // that work_started() has not yet been called for the operation.
106 BOOST_ASIO_DECL void post_immediate_completion(
107 operation* op, bool is_continuation);
109 // Request invocation of the given operation and return immediately. Assumes
110 // that work_started() was previously called for the operation.
111 BOOST_ASIO_DECL void post_deferred_completion(operation* op);
113 // Request invocation of the given operations and return immediately. Assumes
114 // that work_started() was previously called for each operation.
115 BOOST_ASIO_DECL void post_deferred_completions(op_queue<operation>& ops);
117 // Enqueue the given operation following a failed attempt to dispatch the
118 // operation for immediate invocation.
119 BOOST_ASIO_DECL void do_dispatch(operation* op);
121 // Process unfinished operations as part of a shutdownoperation. Assumes that
122 // work_started() was previously called for the operations.
123 BOOST_ASIO_DECL void abandon_operations(op_queue<operation>& ops);
125 // Get the concurrency hint that was used to initialise the scheduler.
126 int concurrency_hint() const
128 return concurrency_hint_;
132 // The mutex type used by this scheduler.
133 typedef conditionally_enabled_mutex mutex;
135 // The event type used by this scheduler.
136 typedef conditionally_enabled_event event;
138 // Structure containing thread-specific data.
139 typedef scheduler_thread_info thread_info;
141 // Run at most one operation. May block.
142 BOOST_ASIO_DECL std::size_t do_run_one(mutex::scoped_lock& lock,
143 thread_info& this_thread, const boost::system::error_code& ec);
145 // Run at most one operation with a timeout. May block.
146 BOOST_ASIO_DECL std::size_t do_wait_one(mutex::scoped_lock& lock,
147 thread_info& this_thread, long usec, const boost::system::error_code& ec);
149 // Poll for at most one operation.
150 BOOST_ASIO_DECL std::size_t do_poll_one(mutex::scoped_lock& lock,
151 thread_info& this_thread, const boost::system::error_code& ec);
153 // Stop the task and all idle threads.
154 BOOST_ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock);
156 // Wake a single idle thread, or the task, and always unlock the mutex.
157 BOOST_ASIO_DECL void wake_one_thread_and_unlock(
158 mutex::scoped_lock& lock);
160 // Helper class to perform task-related operations on block exit.
162 friend struct task_cleanup;
164 // Helper class to call work-related operations on block exit.
166 friend struct work_cleanup;
168 // Whether to optimise for single-threaded use cases.
169 const bool one_thread_;
171 // Mutex to protect access to internal data.
172 mutable mutex mutex_;
174 // Event to wake up blocked threads.
177 // The task to be run by this service.
180 // Operation object to represent the position of the task in the queue.
181 struct task_operation : operation
183 task_operation() : operation(0) {}
186 // Whether the task has been interrupted.
187 bool task_interrupted_;
189 // The count of unfinished work.
190 atomic_count outstanding_work_;
192 // The queue of handlers that are ready to be delivered.
193 op_queue<operation> op_queue_;
195 // Flag to indicate that the dispatcher has been stopped.
198 // Flag to indicate that the dispatcher has been shut down.
201 // The concurrency hint used to initialise the scheduler.
202 const int concurrency_hint_;
205 } // namespace detail
209 #include <boost/asio/detail/pop_options.hpp>
211 #if defined(BOOST_ASIO_HEADER_ONLY)
212 # include <boost/asio/detail/impl/scheduler.ipp>
213 #endif // defined(BOOST_ASIO_HEADER_ONLY)
215 #endif // BOOST_ASIO_DETAIL_SCHEDULER_HPP