]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/execution/blocking_adaptation.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / execution / blocking_adaptation.hpp
CommitLineData
20effc67
TL
1//
2// execution/blocking_adaptation.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2020 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_EXECUTION_BLOCKING_ADAPTATION_HPP
12#define BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_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/detail/event.hpp>
20#include <boost/asio/detail/mutex.hpp>
21#include <boost/asio/detail/type_traits.hpp>
22#include <boost/asio/execution/execute.hpp>
23#include <boost/asio/execution/executor.hpp>
24#include <boost/asio/execution/scheduler.hpp>
25#include <boost/asio/execution/sender.hpp>
26#include <boost/asio/is_applicable_property.hpp>
27#include <boost/asio/prefer.hpp>
28#include <boost/asio/query.hpp>
29#include <boost/asio/require.hpp>
30#include <boost/asio/traits/prefer_member.hpp>
31#include <boost/asio/traits/query_free.hpp>
32#include <boost/asio/traits/query_member.hpp>
33#include <boost/asio/traits/query_static_constexpr_member.hpp>
34#include <boost/asio/traits/require_member.hpp>
35#include <boost/asio/traits/static_query.hpp>
36#include <boost/asio/traits/static_require.hpp>
37
38#include <boost/asio/detail/push_options.hpp>
39
40namespace boost {
41namespace asio {
42
43#if defined(GENERATING_DOCUMENTATION)
44
45namespace execution {
46
47/// A property to describe whether automatic adaptation of an executor is
48/// allowed in order to apply the blocking_adaptation_t::allowed_t property.
49struct blocking_adaptation_t
50{
51 /// The blocking_adaptation_t property applies to executors, senders, and
52 /// schedulers.
53 template <typename T>
54 static constexpr bool is_applicable_property_v =
55 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
56
57 /// The top-level blocking_adaptation_t property cannot be required.
58 static constexpr bool is_requirable = false;
59
60 /// The top-level blocking_adaptation_t property cannot be preferred.
61 static constexpr bool is_preferable = false;
62
63 /// The type returned by queries against an @c any_executor.
64 typedef blocking_adaptation_t polymorphic_query_result_type;
65
66 /// A sub-property that indicates that automatic adaptation is not allowed.
67 struct disallowed_t
68 {
69 /// The blocking_adaptation_t::disallowed_t property applies to executors,
70 /// senders, and schedulers.
71 template <typename T>
72 static constexpr bool is_applicable_property_v =
73 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
74
75 /// The blocking_adaptation_t::disallowed_t property can be required.
76 static constexpr bool is_requirable = true;
77
78 /// The blocking_adaptation_t::disallowed_t property can be preferred.
79 static constexpr bool is_preferable = true;
80
81 /// The type returned by queries against an @c any_executor.
82 typedef blocking_adaptation_t polymorphic_query_result_type;
83
84 /// Default constructor.
85 constexpr disallowed_t();
86
87 /// Get the value associated with a property object.
88 /**
89 * @returns disallowed_t();
90 */
91 static constexpr blocking_adaptation_t value();
92 };
93
94 /// A sub-property that indicates that automatic adaptation is allowed.
95 struct allowed_t
96 {
97 /// The blocking_adaptation_t::allowed_t property applies to executors,
98 /// senders, and schedulers.
99 template <typename T>
100 static constexpr bool is_applicable_property_v =
101 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
102
103 /// The blocking_adaptation_t::allowed_t property can be required.
104 static constexpr bool is_requirable = true;
105
106 /// The blocking_adaptation_t::allowed_t property can be preferred.
107 static constexpr bool is_preferable = false;
108
109 /// The type returned by queries against an @c any_executor.
110 typedef blocking_adaptation_t polymorphic_query_result_type;
111
112 /// Default constructor.
113 constexpr allowed_t();
114
115 /// Get the value associated with a property object.
116 /**
117 * @returns allowed_t();
118 */
119 static constexpr blocking_adaptation_t value();
120 };
121
122 /// A special value used for accessing the blocking_adaptation_t::disallowed_t
123 /// property.
124 static constexpr disallowed_t disallowed;
125
126 /// A special value used for accessing the blocking_adaptation_t::allowed_t
127 /// property.
128 static constexpr allowed_t allowed;
129
130 /// Default constructor.
131 constexpr blocking_adaptation_t();
132
133 /// Construct from a sub-property value.
134 constexpr blocking_adaptation_t(disallowed_t);
135
136 /// Construct from a sub-property value.
137 constexpr blocking_adaptation_t(allowed_t);
138
139 /// Compare property values for equality.
140 friend constexpr bool operator==(
141 const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
142
143 /// Compare property values for inequality.
144 friend constexpr bool operator!=(
145 const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
146};
147
148/// A special value used for accessing the blocking_adaptation_t property.
149constexpr blocking_adaptation_t blocking_adaptation;
150
151} // namespace execution
152
153#else // defined(GENERATING_DOCUMENTATION)
154
155namespace execution {
156namespace detail {
157namespace blocking_adaptation {
158
159template <int I> struct disallowed_t;
160template <int I> struct allowed_t;
161
162} // namespace blocking_adaptation
163
164template <int I = 0>
165struct blocking_adaptation_t
166{
167#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
168 template <typename T>
169 BOOST_ASIO_STATIC_CONSTEXPR(bool,
170 is_applicable_property_v = is_executor<T>::value
171 || is_sender<T>::value || is_scheduler<T>::value);
172#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
173
174 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
175 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
176 typedef blocking_adaptation_t polymorphic_query_result_type;
177
178 typedef detail::blocking_adaptation::disallowed_t<I> disallowed_t;
179 typedef detail::blocking_adaptation::allowed_t<I> allowed_t;
180
181 BOOST_ASIO_CONSTEXPR blocking_adaptation_t()
182 : value_(-1)
183 {
184 }
185
186 BOOST_ASIO_CONSTEXPR blocking_adaptation_t(disallowed_t)
187 : value_(0)
188 {
189 }
190
191 BOOST_ASIO_CONSTEXPR blocking_adaptation_t(allowed_t)
192 : value_(1)
193 {
194 }
195
196#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
197 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
198 template <typename T>
199 static BOOST_ASIO_CONSTEXPR
200 typename traits::query_static_constexpr_member<
201 T, blocking_adaptation_t>::result_type
202 static_query()
203 BOOST_ASIO_NOEXCEPT_IF((
204 traits::query_static_constexpr_member<
205 T, blocking_adaptation_t
206 >::is_noexcept))
207 {
208 return traits::query_static_constexpr_member<
209 T, blocking_adaptation_t>::value();
210 }
211
212 template <typename T>
213 static BOOST_ASIO_CONSTEXPR
214 typename traits::static_query<T, disallowed_t>::result_type
215 static_query(
216 typename enable_if<
217 !traits::query_static_constexpr_member<
218 T, blocking_adaptation_t>::is_valid
219 && !traits::query_member<T, blocking_adaptation_t>::is_valid
220 && traits::static_query<T, disallowed_t>::is_valid
221 >::type* = 0) BOOST_ASIO_NOEXCEPT
222 {
223 return traits::static_query<T, disallowed_t>::value();
224 }
225
226 template <typename T>
227 static BOOST_ASIO_CONSTEXPR
228 typename traits::static_query<T, allowed_t>::result_type
229 static_query(
230 typename enable_if<
231 !traits::query_static_constexpr_member<
232 T, blocking_adaptation_t>::is_valid
233 && !traits::query_member<T, blocking_adaptation_t>::is_valid
234 && !traits::static_query<T, disallowed_t>::is_valid
235 && traits::static_query<T, allowed_t>::is_valid
236 >::type* = 0) BOOST_ASIO_NOEXCEPT
237 {
238 return traits::static_query<T, allowed_t>::value();
239 }
240
241 template <typename E,
242 typename T = decltype(blocking_adaptation_t::static_query<E>())>
243 static BOOST_ASIO_CONSTEXPR const T static_query_v
244 = blocking_adaptation_t::static_query<E>();
245#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
246 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
247
248 friend BOOST_ASIO_CONSTEXPR bool operator==(
249 const blocking_adaptation_t& a, const blocking_adaptation_t& b)
250 {
251 return a.value_ == b.value_;
252 }
253
254 friend BOOST_ASIO_CONSTEXPR bool operator!=(
255 const blocking_adaptation_t& a, const blocking_adaptation_t& b)
256 {
257 return a.value_ != b.value_;
258 }
259
260 struct convertible_from_blocking_adaptation_t
261 {
262 BOOST_ASIO_CONSTEXPR convertible_from_blocking_adaptation_t(
263 blocking_adaptation_t)
264 {
265 }
266 };
267
268 template <typename Executor>
269 friend BOOST_ASIO_CONSTEXPR blocking_adaptation_t query(
270 const Executor& ex, convertible_from_blocking_adaptation_t,
271 typename enable_if<
272 can_query<const Executor&, disallowed_t>::value
273 >::type* = 0)
274#if !defined(__clang__) // Clang crashes if noexcept is used here.
275#if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified.
276 BOOST_ASIO_NOEXCEPT_IF((
277 is_nothrow_query<const Executor&,
278 blocking_adaptation_t<>::disallowed_t>::value))
279#else // defined(BOOST_ASIO_MSVC)
280 BOOST_ASIO_NOEXCEPT_IF((
281 is_nothrow_query<const Executor&, disallowed_t>::value))
282#endif // defined(BOOST_ASIO_MSVC)
283#endif // !defined(__clang__)
284 {
285 return boost::asio::query(ex, disallowed_t());
286 }
287
288 template <typename Executor>
289 friend BOOST_ASIO_CONSTEXPR blocking_adaptation_t query(
290 const Executor& ex, convertible_from_blocking_adaptation_t,
291 typename enable_if<
292 !can_query<const Executor&, disallowed_t>::value
293 && can_query<const Executor&, allowed_t>::value
294 >::type* = 0)
295#if !defined(__clang__) // Clang crashes if noexcept is used here.
296#if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified.
297 BOOST_ASIO_NOEXCEPT_IF((
298 is_nothrow_query<const Executor&,
299 blocking_adaptation_t<>::allowed_t>::value))
300#else // defined(BOOST_ASIO_MSVC)
301 BOOST_ASIO_NOEXCEPT_IF((
302 is_nothrow_query<const Executor&, allowed_t>::value))
303#endif // defined(BOOST_ASIO_MSVC)
304#endif // !defined(__clang__)
305 {
306 return boost::asio::query(ex, allowed_t());
307 }
308
309 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed);
310 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed);
311
312#if !defined(BOOST_ASIO_HAS_CONSTEXPR)
313 static const blocking_adaptation_t instance;
314#endif // !defined(BOOST_ASIO_HAS_CONSTEXPR)
315
316private:
317 int value_;
318};
319
320#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
321 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
322template <int I> template <typename E, typename T>
323const T blocking_adaptation_t<I>::static_query_v;
324#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
325 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
326
327#if !defined(BOOST_ASIO_HAS_CONSTEXPR)
328template <int I>
329const blocking_adaptation_t<I> blocking_adaptation_t<I>::instance;
330#endif
331
332template <int I>
333const typename blocking_adaptation_t<I>::disallowed_t
334blocking_adaptation_t<I>::disallowed;
335
336template <int I>
337const typename blocking_adaptation_t<I>::allowed_t
338blocking_adaptation_t<I>::allowed;
339
340namespace blocking_adaptation {
341
342template <int I = 0>
343struct disallowed_t
344{
345#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
346 template <typename T>
347 BOOST_ASIO_STATIC_CONSTEXPR(bool,
348 is_applicable_property_v = is_executor<T>::value
349 || is_sender<T>::value || is_scheduler<T>::value);
350#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
351
352 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
353 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
354 typedef blocking_adaptation_t<I> polymorphic_query_result_type;
355
356 BOOST_ASIO_CONSTEXPR disallowed_t()
357 {
358 }
359
360#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
361 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
362 template <typename T>
363 static BOOST_ASIO_CONSTEXPR
364 typename traits::query_static_constexpr_member<T, disallowed_t>::result_type
365 static_query()
366 BOOST_ASIO_NOEXCEPT_IF((
367 traits::query_static_constexpr_member<T, disallowed_t>::is_noexcept))
368 {
369 return traits::query_static_constexpr_member<T, disallowed_t>::value();
370 }
371
372 template <typename T>
373 static BOOST_ASIO_CONSTEXPR disallowed_t static_query(
374 typename enable_if<
375 !traits::query_static_constexpr_member<T, disallowed_t>::is_valid
376 && !traits::query_member<T, disallowed_t>::is_valid
377 && !traits::query_free<T, disallowed_t>::is_valid
378 && !can_query<T, allowed_t<I> >::value
379 >::type* = 0) BOOST_ASIO_NOEXCEPT
380 {
381 return disallowed_t();
382 }
383
384 template <typename E, typename T = decltype(disallowed_t::static_query<E>())>
385 static BOOST_ASIO_CONSTEXPR const T static_query_v
386 = disallowed_t::static_query<E>();
387#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
388 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
389
390 static BOOST_ASIO_CONSTEXPR blocking_adaptation_t<I> value()
391 {
392 return disallowed_t();
393 }
394
395 friend BOOST_ASIO_CONSTEXPR bool operator==(
396 const disallowed_t&, const disallowed_t&)
397 {
398 return true;
399 }
400
401 friend BOOST_ASIO_CONSTEXPR bool operator!=(
402 const disallowed_t&, const disallowed_t&)
403 {
404 return false;
405 }
406};
407
408#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
409 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
410template <int I> template <typename E, typename T>
411const T disallowed_t<I>::static_query_v;
412#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
413 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
414
415template <typename Executor>
416class adapter
417{
418public:
419 adapter(int, const Executor& e) BOOST_ASIO_NOEXCEPT
420 : executor_(e)
421 {
422 }
423
424 adapter(const adapter& other) BOOST_ASIO_NOEXCEPT
425 : executor_(other.executor_)
426 {
427 }
428
429#if defined(BOOST_ASIO_HAS_MOVE)
430 adapter(adapter&& other) BOOST_ASIO_NOEXCEPT
431 : executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_))
432 {
433 }
434#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
435
436 template <int I>
437 static BOOST_ASIO_CONSTEXPR allowed_t<I> query(
438 blocking_adaptation_t<I>) BOOST_ASIO_NOEXCEPT
439 {
440 return allowed_t<I>();
441 }
442
443 template <int I>
444 static BOOST_ASIO_CONSTEXPR allowed_t<I> query(
445 allowed_t<I>) BOOST_ASIO_NOEXCEPT
446 {
447 return allowed_t<I>();
448 }
449
450 template <int I>
451 static BOOST_ASIO_CONSTEXPR allowed_t<I> query(
452 disallowed_t<I>) BOOST_ASIO_NOEXCEPT
453 {
454 return allowed_t<I>();
455 }
456
457 template <typename Property>
458 typename enable_if<
459 can_query<const Executor&, Property>::value,
460 typename query_result<const Executor&, Property>::type
461 >::type query(const Property& p) const
462 BOOST_ASIO_NOEXCEPT_IF((
463 is_nothrow_query<const Executor&, Property>::value))
464 {
465 return boost::asio::query(executor_, p);
466 }
467
468 template <int I>
469 Executor require(disallowed_t<I>) const BOOST_ASIO_NOEXCEPT
470 {
471 return executor_;
472 }
473
474 template <typename Property>
475 typename enable_if<
476 can_require<const Executor&, Property>::value,
477 adapter<typename decay<
478 typename require_result<const Executor&, Property>::type
479 >::type>
480 >::type require(const Property& p) const
481 BOOST_ASIO_NOEXCEPT_IF((
482 is_nothrow_require<const Executor&, Property>::value))
483 {
484 return adapter<typename decay<
485 typename require_result<const Executor&, Property>::type
486 >::type>(0, boost::asio::require(executor_, p));
487 }
488
489 template <typename Property>
490 typename enable_if<
491 can_prefer<const Executor&, Property>::value,
492 adapter<typename decay<
493 typename prefer_result<const Executor&, Property>::type
494 >::type>
495 >::type prefer(const Property& p) const
496 BOOST_ASIO_NOEXCEPT_IF((
497 is_nothrow_prefer<const Executor&, Property>::value))
498 {
499 return adapter<typename decay<
500 typename prefer_result<const Executor&, Property>::type
501 >::type>(0, boost::asio::prefer(executor_, p));
502 }
503
504 template <typename Function>
505 typename enable_if<
506 execution::can_execute<const Executor&, Function>::value
507 >::type execute(BOOST_ASIO_MOVE_ARG(Function) f) const
508 {
509 execution::execute(executor_, BOOST_ASIO_MOVE_CAST(Function)(f));
510 }
511
512 friend bool operator==(const adapter& a, const adapter& b) BOOST_ASIO_NOEXCEPT
513 {
514 return a.executor_ == b.executor_;
515 }
516
517 friend bool operator!=(const adapter& a, const adapter& b) BOOST_ASIO_NOEXCEPT
518 {
519 return a.executor_ != b.executor_;
520 }
521
522private:
523 Executor executor_;
524};
525
526template <int I = 0>
527struct allowed_t
528{
529#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
530 template <typename T>
531 BOOST_ASIO_STATIC_CONSTEXPR(bool,
532 is_applicable_property_v = is_executor<T>::value
533 || is_sender<T>::value || is_scheduler<T>::value);
534#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
535
536 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
537 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
538 typedef blocking_adaptation_t<I> polymorphic_query_result_type;
539
540 BOOST_ASIO_CONSTEXPR allowed_t()
541 {
542 }
543
544#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
545 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
546 template <typename T>
547 static BOOST_ASIO_CONSTEXPR
548 typename traits::query_static_constexpr_member<T, allowed_t>::result_type
549 static_query()
550 BOOST_ASIO_NOEXCEPT_IF((
551 traits::query_static_constexpr_member<T, allowed_t>::is_noexcept))
552 {
553 return traits::query_static_constexpr_member<T, allowed_t>::value();
554 }
555
556 template <typename E, typename T = decltype(allowed_t::static_query<E>())>
557 static BOOST_ASIO_CONSTEXPR const T static_query_v
558 = allowed_t::static_query<E>();
559#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
560 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
561
562 static BOOST_ASIO_CONSTEXPR blocking_adaptation_t<I> value()
563 {
564 return allowed_t();
565 }
566
567 friend BOOST_ASIO_CONSTEXPR bool operator==(
568 const allowed_t&, const allowed_t&)
569 {
570 return true;
571 }
572
573 friend BOOST_ASIO_CONSTEXPR bool operator!=(
574 const allowed_t&, const allowed_t&)
575 {
576 return false;
577 }
578
579 template <typename Executor>
580 friend adapter<Executor> require(
581 const Executor& e, const allowed_t&,
582 typename enable_if<
583 is_executor<Executor>::value
584 >::type* = 0)
585 {
586 return adapter<Executor>(0, e);
587 }
588};
589
590#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
591 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
592template <int I> template <typename E, typename T>
593const T allowed_t<I>::static_query_v;
594#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
595 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
596
597template <typename Function>
598class blocking_execute_state
599{
600public:
601 template <typename F>
602 blocking_execute_state(BOOST_ASIO_MOVE_ARG(F) f)
603 : func_(BOOST_ASIO_MOVE_CAST(F)(f)),
604 is_complete_(false)
605 {
606 }
607
608 template <typename Executor>
609 void execute_and_wait(BOOST_ASIO_MOVE_ARG(Executor) ex)
610 {
611 handler h = { this };
612 execution::execute(BOOST_ASIO_MOVE_CAST(Executor)(ex), h);
613 boost::asio::detail::mutex::scoped_lock lock(mutex_);
614 while (!is_complete_)
615 event_.wait(lock);
616 }
617
618 struct cleanup
619 {
620 ~cleanup()
621 {
622 boost::asio::detail::mutex::scoped_lock lock(state_->mutex_);
623 state_->is_complete_ = true;
624 state_->event_.unlock_and_signal_one_for_destruction(lock);
625 }
626
627 blocking_execute_state* state_;
628 };
629
630 struct handler
631 {
632 void operator()()
633 {
634 cleanup c = { state_ };
635 state_->func_();
636 }
637
638 blocking_execute_state* state_;
639 };
640
641 Function func_;
642 boost::asio::detail::mutex mutex_;
643 boost::asio::detail::event event_;
644 bool is_complete_;
645};
646
647template <typename Executor, typename Function>
648void blocking_execute(
649 BOOST_ASIO_MOVE_ARG(Executor) ex,
650 BOOST_ASIO_MOVE_ARG(Function) func)
651{
652 typedef typename decay<Function>::type func_t;
653 blocking_execute_state<func_t> state(BOOST_ASIO_MOVE_CAST(Function)(func));
654 state.execute_and_wait(ex);
655}
656
657} // namespace blocking_adaptation
658} // namespace detail
659
660typedef detail::blocking_adaptation_t<> blocking_adaptation_t;
661
662#if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
663constexpr blocking_adaptation_t blocking_adaptation;
664#else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
665namespace { static const blocking_adaptation_t&
666 blocking_adaptation = blocking_adaptation_t::instance; }
667#endif
668
669} // namespace execution
670
671#if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
672
673template <typename T>
674struct is_applicable_property<T, execution::blocking_adaptation_t>
675 : integral_constant<bool,
676 execution::is_executor<T>::value
677 || execution::is_sender<T>::value
678 || execution::is_scheduler<T>::value>
679{
680};
681
682template <typename T>
683struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t>
684 : integral_constant<bool,
685 execution::is_executor<T>::value
686 || execution::is_sender<T>::value
687 || execution::is_scheduler<T>::value>
688{
689};
690
691template <typename T>
692struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t>
693 : integral_constant<bool,
694 execution::is_executor<T>::value
695 || execution::is_sender<T>::value
696 || execution::is_scheduler<T>::value>
697{
698};
699
700#endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
701
702namespace traits {
703
704#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
705
706template <typename T>
707struct query_free_default<T, execution::blocking_adaptation_t,
708 typename enable_if<
709 can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
710 >::type>
711{
712 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
713 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T,
714 execution::blocking_adaptation_t::disallowed_t>::value));
715
716 typedef execution::blocking_adaptation_t result_type;
717};
718
719template <typename T>
720struct query_free_default<T, execution::blocking_adaptation_t,
721 typename enable_if<
722 !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
723 && can_query<T, execution::blocking_adaptation_t::allowed_t>::value
724 >::type>
725{
726 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
727 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
728 (is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value));
729
730 typedef execution::blocking_adaptation_t result_type;
731};
732
733#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
734
735#if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
736 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
737
738template <typename T>
739struct static_query<T, execution::blocking_adaptation_t,
740 typename enable_if<
741 traits::query_static_constexpr_member<T,
742 execution::blocking_adaptation_t>::is_valid
743 >::type>
744{
745 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
746 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
747
748 typedef typename traits::query_static_constexpr_member<T,
749 execution::blocking_adaptation_t>::result_type result_type;
750
751 static BOOST_ASIO_CONSTEXPR result_type value()
752 {
753 return traits::query_static_constexpr_member<T,
754 execution::blocking_adaptation_t>::value();
755 }
756};
757
758template <typename T>
759struct static_query<T, execution::blocking_adaptation_t,
760 typename enable_if<
761 !traits::query_static_constexpr_member<T,
762 execution::blocking_adaptation_t>::is_valid
763 && !traits::query_member<T,
764 execution::blocking_adaptation_t>::is_valid
765 && traits::static_query<T,
766 execution::blocking_adaptation_t::disallowed_t>::is_valid
767 >::type>
768{
769 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
770 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
771
772 typedef typename traits::static_query<T,
773 execution::blocking_adaptation_t::disallowed_t>::result_type result_type;
774
775 static BOOST_ASIO_CONSTEXPR result_type value()
776 {
777 return traits::static_query<T,
778 execution::blocking_adaptation_t::disallowed_t>::value();
779 }
780};
781
782template <typename T>
783struct static_query<T, execution::blocking_adaptation_t,
784 typename enable_if<
785 !traits::query_static_constexpr_member<T,
786 execution::blocking_adaptation_t>::is_valid
787 && !traits::query_member<T,
788 execution::blocking_adaptation_t>::is_valid
789 && !traits::static_query<T,
790 execution::blocking_adaptation_t::disallowed_t>::is_valid
791 && traits::static_query<T,
792 execution::blocking_adaptation_t::allowed_t>::is_valid
793 >::type>
794{
795 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
796 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
797
798 typedef typename traits::static_query<T,
799 execution::blocking_adaptation_t::allowed_t>::result_type result_type;
800
801 static BOOST_ASIO_CONSTEXPR result_type value()
802 {
803 return traits::static_query<T,
804 execution::blocking_adaptation_t::allowed_t>::value();
805 }
806};
807
808template <typename T>
809struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
810 typename enable_if<
811 traits::query_static_constexpr_member<T,
812 execution::blocking_adaptation_t::disallowed_t>::is_valid
813 >::type>
814{
815 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
816 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
817
818 typedef typename traits::query_static_constexpr_member<T,
819 execution::blocking_adaptation_t::disallowed_t>::result_type result_type;
820
821 static BOOST_ASIO_CONSTEXPR result_type value()
822 {
823 return traits::query_static_constexpr_member<T,
824 execution::blocking_adaptation_t::disallowed_t>::value();
825 }
826};
827
828template <typename T>
829struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
830 typename enable_if<
831 !traits::query_static_constexpr_member<T,
832 execution::blocking_adaptation_t::disallowed_t>::is_valid
833 && !traits::query_member<T,
834 execution::blocking_adaptation_t::disallowed_t>::is_valid
835 && !traits::query_free<T,
836 execution::blocking_adaptation_t::disallowed_t>::is_valid
837 && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value
838 >::type>
839{
840 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
841 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
842
843 typedef execution::blocking_adaptation_t::disallowed_t result_type;
844
845 static BOOST_ASIO_CONSTEXPR result_type value()
846 {
847 return result_type();
848 }
849};
850
851template <typename T>
852struct static_query<T, execution::blocking_adaptation_t::allowed_t,
853 typename enable_if<
854 traits::query_static_constexpr_member<T,
855 execution::blocking_adaptation_t::allowed_t>::is_valid
856 >::type>
857{
858 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
859 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
860
861 typedef typename traits::query_static_constexpr_member<T,
862 execution::blocking_adaptation_t::allowed_t>::result_type result_type;
863
864 static BOOST_ASIO_CONSTEXPR result_type value()
865 {
866 return traits::query_static_constexpr_member<T,
867 execution::blocking_adaptation_t::allowed_t>::value();
868 }
869};
870
871#endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
872 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
873
874#if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
875
876template <typename T>
877struct static_require<T, execution::blocking_adaptation_t::disallowed_t,
878 typename enable_if<
879 static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid
880 >::type>
881{
882 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid =
883 (is_same<typename static_query<T,
884 execution::blocking_adaptation_t::disallowed_t>::result_type,
885 execution::blocking_adaptation_t::disallowed_t>::value));
886};
887
888template <typename T>
889struct static_require<T, execution::blocking_adaptation_t::allowed_t,
890 typename enable_if<
891 static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid
892 >::type>
893{
894 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid =
895 (is_same<typename static_query<T,
896 execution::blocking_adaptation_t::allowed_t>::result_type,
897 execution::blocking_adaptation_t::allowed_t>::value));
898};
899
900#endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
901
902#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
903
904template <typename T>
905struct require_free_default<T, execution::blocking_adaptation_t::allowed_t,
906 typename enable_if<
907 is_same<T, typename decay<T>::type>::value
908 && execution::is_executor<T>::value
909 >::type>
910{
911 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
912 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
913 typedef execution::detail::blocking_adaptation::adapter<T> result_type;
914};
915
916#endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
917
918#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
919
920template <typename Executor>
921struct equality_comparable<
922 execution::detail::blocking_adaptation::adapter<Executor> >
923{
924 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
925 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
926};
927
928#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
929
930#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
931
932template <typename Executor, typename Function>
933struct execute_member<
934 execution::detail::blocking_adaptation::adapter<Executor>, Function>
935{
936 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
937 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
938 typedef void result_type;
939};
940
941#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
942
943#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
944
945template <typename Executor, int I>
946struct query_static_constexpr_member<
947 execution::detail::blocking_adaptation::adapter<Executor>,
948 execution::detail::blocking_adaptation_t<I> >
949{
950 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
951 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
952 typedef execution::blocking_adaptation_t::allowed_t result_type;
953
954 static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT
955 {
956 return result_type();
957 }
958};
959
960template <typename Executor, int I>
961struct query_static_constexpr_member<
962 execution::detail::blocking_adaptation::adapter<Executor>,
963 execution::detail::blocking_adaptation::allowed_t<I> >
964{
965 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
966 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
967 typedef execution::blocking_adaptation_t::allowed_t result_type;
968
969 static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT
970 {
971 return result_type();
972 }
973};
974
975template <typename Executor, int I>
976struct query_static_constexpr_member<
977 execution::detail::blocking_adaptation::adapter<Executor>,
978 execution::detail::blocking_adaptation::disallowed_t<I> >
979{
980 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
981 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
982 typedef execution::blocking_adaptation_t::allowed_t result_type;
983
984 static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT
985 {
986 return result_type();
987 }
988};
989
990#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
991
992#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
993
994template <typename Executor, typename Property>
995struct query_member<
996 execution::detail::blocking_adaptation::adapter<Executor>, Property,
997 typename enable_if<
998 can_query<const Executor&, Property>::value
999 >::type>
1000{
1001 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1002 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1003 (is_nothrow_query<Executor, Property>::value));
1004 typedef typename query_result<Executor, Property>::type result_type;
1005};
1006
1007#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
1008
1009#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1010
1011template <typename Executor, int I>
1012struct require_member<
1013 execution::detail::blocking_adaptation::adapter<Executor>,
1014 execution::detail::blocking_adaptation::disallowed_t<I> >
1015{
1016 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1017 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1018 typedef Executor result_type;
1019};
1020
1021template <typename Executor, typename Property>
1022struct require_member<
1023 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1024 typename enable_if<
1025 can_require<const Executor&, Property>::value
1026 >::type>
1027{
1028 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1029 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1030 (is_nothrow_require<Executor, Property>::value));
1031 typedef execution::detail::blocking_adaptation::adapter<typename decay<
1032 typename require_result<Executor, Property>::type
1033 >::type> result_type;
1034};
1035
1036#endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1037
1038#if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1039
1040template <typename Executor, typename Property>
1041struct prefer_member<
1042 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1043 typename enable_if<
1044 can_prefer<const Executor&, Property>::value
1045 >::type>
1046{
1047 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1048 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1049 (is_nothrow_prefer<Executor, Property>::value));
1050 typedef execution::detail::blocking_adaptation::adapter<typename decay<
1051 typename prefer_result<Executor, Property>::type
1052 >::type> result_type;
1053};
1054
1055#endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1056
1057} // namespace traits
1058
1059#endif // defined(GENERATING_DOCUMENTATION)
1060
1061} // namespace asio
1062} // namespace boost
1063
1064#include <boost/asio/detail/pop_options.hpp>
1065
1066#endif // BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP