Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/asio/strand.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // | |
2 // strand.hpp | |
3 // ~~~~~~~~~~ | |
4 // | |
5 // Copyright (c) 2003-2013 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_STRAND_HPP | |
12 #define BOOST_ASIO_STRAND_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 #include <boost/asio/async_result.hpp> | |
20 #include <boost/asio/detail/handler_type_requirements.hpp> | |
21 #include <boost/asio/detail/strand_service.hpp> | |
22 #include <boost/asio/detail/wrapped_handler.hpp> | |
23 #include <boost/asio/io_service.hpp> | |
24 | |
25 #include <boost/asio/detail/push_options.hpp> | |
26 | |
27 namespace boost { | |
28 namespace asio { | |
29 | |
30 /// Provides serialised handler execution. | |
31 /** | |
32 * The io_service::strand class provides the ability to post and dispatch | |
33 * handlers with the guarantee that none of those handlers will execute | |
34 * concurrently. | |
35 * | |
36 * @par Order of handler invocation | |
37 * Given: | |
38 * | |
39 * @li a strand object @c s | |
40 * | |
41 * @li an object @c a meeting completion handler requirements | |
42 * | |
43 * @li an object @c a1 which is an arbitrary copy of @c a made by the | |
44 * implementation | |
45 * | |
46 * @li an object @c b meeting completion handler requirements | |
47 * | |
48 * @li an object @c b1 which is an arbitrary copy of @c b made by the | |
49 * implementation | |
50 * | |
51 * if any of the following conditions are true: | |
52 * | |
53 * @li @c s.post(a) happens-before @c s.post(b) | |
54 * | |
55 * @li @c s.post(a) happens-before @c s.dispatch(b), where the latter is | |
56 * performed outside the strand | |
57 * | |
58 * @li @c s.dispatch(a) happens-before @c s.post(b), where the former is | |
59 * performed outside the strand | |
60 * | |
61 * @li @c s.dispatch(a) happens-before @c s.dispatch(b), where both are | |
62 * performed outside the strand | |
63 * | |
64 * then @c asio_handler_invoke(a1, &a1) happens-before | |
65 * @c asio_handler_invoke(b1, &b1). | |
66 * | |
67 * Note that in the following case: | |
68 * @code async_op_1(..., s.wrap(a)); | |
69 * async_op_2(..., s.wrap(b)); @endcode | |
70 * the completion of the first async operation will perform @c s.dispatch(a), | |
71 * and the second will perform @c s.dispatch(b), but the order in which those | |
72 * are performed is unspecified. That is, you cannot state whether one | |
73 * happens-before the other. Therefore none of the above conditions are met and | |
74 * no ordering guarantee is made. | |
75 * | |
76 * @note The implementation makes no guarantee that handlers posted or | |
77 * dispatched through different @c strand objects will be invoked concurrently. | |
78 * | |
79 * @par Thread Safety | |
80 * @e Distinct @e objects: Safe.@n | |
81 * @e Shared @e objects: Safe. | |
82 * | |
83 * @par Concepts: | |
84 * Dispatcher. | |
85 */ | |
86 class io_service::strand | |
87 { | |
88 public: | |
89 /// Constructor. | |
90 /** | |
91 * Constructs the strand. | |
92 * | |
93 * @param io_service The io_service object that the strand will use to | |
94 * dispatch handlers that are ready to be run. | |
95 */ | |
96 explicit strand(boost::asio::io_service& io_service) | |
97 : service_(boost::asio::use_service< | |
98 boost::asio::detail::strand_service>(io_service)) | |
99 { | |
100 service_.construct(impl_); | |
101 } | |
102 | |
103 /// Destructor. | |
104 /** | |
105 * Destroys a strand. | |
106 * | |
107 * Handlers posted through the strand that have not yet been invoked will | |
108 * still be dispatched in a way that meets the guarantee of non-concurrency. | |
109 */ | |
110 ~strand() | |
111 { | |
112 } | |
113 | |
114 /// Get the io_service associated with the strand. | |
115 /** | |
116 * This function may be used to obtain the io_service object that the strand | |
117 * uses to dispatch handlers for asynchronous operations. | |
118 * | |
119 * @return A reference to the io_service object that the strand will use to | |
120 * dispatch handlers. Ownership is not transferred to the caller. | |
121 */ | |
122 boost::asio::io_service& get_io_service() | |
123 { | |
124 return service_.get_io_service(); | |
125 } | |
126 | |
127 /// Request the strand to invoke the given handler. | |
128 /** | |
129 * This function is used to ask the strand to execute the given handler. | |
130 * | |
131 * The strand object guarantees that handlers posted or dispatched through | |
132 * the strand will not be executed concurrently. The handler may be executed | |
133 * inside this function if the guarantee can be met. If this function is | |
134 * called from within a handler that was posted or dispatched through the same | |
135 * strand, then the new handler will be executed immediately. | |
136 * | |
137 * The strand's guarantee is in addition to the guarantee provided by the | |
138 * underlying io_service. The io_service guarantees that the handler will only | |
139 * be called in a thread in which the io_service's run member function is | |
140 * currently being invoked. | |
141 * | |
142 * @param handler The handler to be called. The strand will make a copy of the | |
143 * handler object as required. The function signature of the handler must be: | |
144 * @code void handler(); @endcode | |
145 */ | |
146 template <typename CompletionHandler> | |
147 BOOST_ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ()) | |
148 dispatch(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) | |
149 { | |
150 // If you get an error on the following line it means that your handler does | |
151 // not meet the documented type requirements for a CompletionHandler. | |
152 BOOST_ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check; | |
153 | |
154 detail::async_result_init< | |
155 CompletionHandler, void ()> init( | |
156 BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); | |
157 | |
158 service_.dispatch(impl_, init.handler); | |
159 | |
160 return init.result.get(); | |
161 } | |
162 | |
163 /// Request the strand to invoke the given handler and return | |
164 /// immediately. | |
165 /** | |
166 * This function is used to ask the strand to execute the given handler, but | |
167 * without allowing the strand to call the handler from inside this function. | |
168 * | |
169 * The strand object guarantees that handlers posted or dispatched through | |
170 * the strand will not be executed concurrently. The strand's guarantee is in | |
171 * addition to the guarantee provided by the underlying io_service. The | |
172 * io_service guarantees that the handler will only be called in a thread in | |
173 * which the io_service's run member function is currently being invoked. | |
174 * | |
175 * @param handler The handler to be called. The strand will make a copy of the | |
176 * handler object as required. The function signature of the handler must be: | |
177 * @code void handler(); @endcode | |
178 */ | |
179 template <typename CompletionHandler> | |
180 BOOST_ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ()) | |
181 post(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) | |
182 { | |
183 // If you get an error on the following line it means that your handler does | |
184 // not meet the documented type requirements for a CompletionHandler. | |
185 BOOST_ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check; | |
186 | |
187 detail::async_result_init< | |
188 CompletionHandler, void ()> init( | |
189 BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); | |
190 | |
191 service_.post(impl_, init.handler); | |
192 | |
193 return init.result.get(); | |
194 } | |
195 | |
196 /// Create a new handler that automatically dispatches the wrapped handler | |
197 /// on the strand. | |
198 /** | |
199 * This function is used to create a new handler function object that, when | |
200 * invoked, will automatically pass the wrapped handler to the strand's | |
201 * dispatch function. | |
202 * | |
203 * @param handler The handler to be wrapped. The strand will make a copy of | |
204 * the handler object as required. The function signature of the handler must | |
205 * be: @code void handler(A1 a1, ... An an); @endcode | |
206 * | |
207 * @return A function object that, when invoked, passes the wrapped handler to | |
208 * the strand's dispatch function. Given a function object with the signature: | |
209 * @code R f(A1 a1, ... An an); @endcode | |
210 * If this function object is passed to the wrap function like so: | |
211 * @code strand.wrap(f); @endcode | |
212 * then the return value is a function object with the signature | |
213 * @code void g(A1 a1, ... An an); @endcode | |
214 * that, when invoked, executes code equivalent to: | |
215 * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode | |
216 */ | |
217 template <typename Handler> | |
218 #if defined(GENERATING_DOCUMENTATION) | |
219 unspecified | |
220 #else | |
221 detail::wrapped_handler<strand, Handler, detail::is_continuation_if_running> | |
222 #endif | |
223 wrap(Handler handler) | |
224 { | |
225 return detail::wrapped_handler<io_service::strand, Handler, | |
226 detail::is_continuation_if_running>(*this, handler); | |
227 } | |
228 | |
229 /// Determine whether the strand is running in the current thread. | |
230 /** | |
231 * @return @c true if the current thread is executing a handler that was | |
232 * submitted to the strand using post(), dispatch() or wrap(). Otherwise | |
233 * returns @c false. | |
234 */ | |
235 bool running_in_this_thread() const | |
236 { | |
237 return service_.running_in_this_thread(impl_); | |
238 } | |
239 | |
240 private: | |
241 boost::asio::detail::strand_service& service_; | |
242 boost::asio::detail::strand_service::implementation_type impl_; | |
243 }; | |
244 | |
245 /// Typedef for backwards compatibility. | |
246 typedef boost::asio::io_service::strand strand; | |
247 | |
248 } // namespace asio | |
249 } // namespace boost | |
250 | |
251 #include <boost/asio/detail/pop_options.hpp> | |
252 | |
253 #endif // BOOST_ASIO_STRAND_HPP |