]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/detail/scheduler.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / detail / scheduler.hpp
1 //
2 // detail/scheduler.hpp
3 // ~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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_SCHEDULER_HPP
12 #define BOOST_ASIO_DETAIL_SCHEDULER_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 #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>
29
30 #include <boost/asio/detail/push_options.hpp>
31
32 namespace boost {
33 namespace asio {
34 namespace detail {
35
36 struct scheduler_thread_info;
37
38 class scheduler
39 : public execution_context_service_base<scheduler>,
40 public thread_context
41 {
42 public:
43 typedef scheduler_operation operation;
44
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);
49
50 // Destroy all user-defined handler objects owned by the service.
51 BOOST_ASIO_DECL void shutdown();
52
53 // Initialise the task, if required.
54 BOOST_ASIO_DECL void init_task();
55
56 // Run the event loop until interrupted or no more work.
57 BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec);
58
59 // Run until interrupted or one operation is performed.
60 BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec);
61
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);
65
66 // Poll for operations without blocking.
67 BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec);
68
69 // Poll for one operation without blocking.
70 BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec);
71
72 // Interrupt the event processing loop.
73 BOOST_ASIO_DECL void stop();
74
75 // Determine whether the scheduler is stopped.
76 BOOST_ASIO_DECL bool stopped() const;
77
78 // Restart in preparation for a subsequent run invocation.
79 BOOST_ASIO_DECL void restart();
80
81 // Notify that some work has started.
82 void work_started()
83 {
84 ++outstanding_work_;
85 }
86
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();
90
91 // Notify that some work has finished.
92 void work_finished()
93 {
94 if (--outstanding_work_ == 0)
95 stop();
96 }
97
98 // Return whether a handler can be dispatched immediately.
99 bool can_dispatch()
100 {
101 return thread_call_stack::contains(this) != 0;
102 }
103
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);
108
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);
112
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);
116
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);
120
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);
124
125 // Get the concurrency hint that was used to initialise the scheduler.
126 int concurrency_hint() const
127 {
128 return concurrency_hint_;
129 }
130
131 private:
132 // The mutex type used by this scheduler.
133 typedef conditionally_enabled_mutex mutex;
134
135 // The event type used by this scheduler.
136 typedef conditionally_enabled_event event;
137
138 // Structure containing thread-specific data.
139 typedef scheduler_thread_info thread_info;
140
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);
144
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);
148
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);
152
153 // Stop the task and all idle threads.
154 BOOST_ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock);
155
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);
159
160 // Helper class to perform task-related operations on block exit.
161 struct task_cleanup;
162 friend struct task_cleanup;
163
164 // Helper class to call work-related operations on block exit.
165 struct work_cleanup;
166 friend struct work_cleanup;
167
168 // Whether to optimise for single-threaded use cases.
169 const bool one_thread_;
170
171 // Mutex to protect access to internal data.
172 mutable mutex mutex_;
173
174 // Event to wake up blocked threads.
175 event wakeup_event_;
176
177 // The task to be run by this service.
178 reactor* task_;
179
180 // Operation object to represent the position of the task in the queue.
181 struct task_operation : operation
182 {
183 task_operation() : operation(0) {}
184 } task_operation_;
185
186 // Whether the task has been interrupted.
187 bool task_interrupted_;
188
189 // The count of unfinished work.
190 atomic_count outstanding_work_;
191
192 // The queue of handlers that are ready to be delivered.
193 op_queue<operation> op_queue_;
194
195 // Flag to indicate that the dispatcher has been stopped.
196 bool stopped_;
197
198 // Flag to indicate that the dispatcher has been shut down.
199 bool shutdown_;
200
201 // The concurrency hint used to initialise the scheduler.
202 const int concurrency_hint_;
203 };
204
205 } // namespace detail
206 } // namespace asio
207 } // namespace boost
208
209 #include <boost/asio/detail/pop_options.hpp>
210
211 #if defined(BOOST_ASIO_HEADER_ONLY)
212 # include <boost/asio/detail/impl/scheduler.ipp>
213 #endif // defined(BOOST_ASIO_HEADER_ONLY)
214
215 #endif // BOOST_ASIO_DETAIL_SCHEDULER_HPP