File indexing completed on 2026-08-16 08:38:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_THREAD_POOL_HPP
0012 #define BOOST_ASIO_THREAD_POOL_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/atomic_count.hpp>
0020 #include <boost/asio/detail/scheduler.hpp>
0021 #include <boost/asio/detail/thread_group.hpp>
0022 #include <boost/asio/execution.hpp>
0023 #include <boost/asio/execution_context.hpp>
0024
0025 #include <boost/asio/detail/push_options.hpp>
0026
0027 namespace boost {
0028 namespace asio {
0029 namespace detail {
0030 struct thread_pool_bits
0031 {
0032 static constexpr unsigned int blocking_never = 1;
0033 static constexpr unsigned int blocking_always = 2;
0034 static constexpr unsigned int blocking_mask = 3;
0035 static constexpr unsigned int relationship_continuation = 4;
0036 static constexpr unsigned int outstanding_work_tracked = 8;
0037 };
0038 }
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 class thread_pool
0087 : public execution_context
0088 {
0089 public:
0090 template <typename Allocator, unsigned int Bits>
0091 class basic_executor_type;
0092
0093 template <typename Allocator, unsigned int Bits>
0094 friend class basic_executor_type;
0095
0096
0097 typedef basic_executor_type<std::allocator<void>, 0> executor_type;
0098
0099 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
0100
0101 BOOST_ASIO_DECL thread_pool();
0102
0103
0104
0105
0106
0107
0108
0109 template <typename Allocator>
0110 thread_pool(allocator_arg_t, const Allocator& a);
0111 #endif
0112
0113
0114
0115
0116
0117 BOOST_ASIO_DECL explicit thread_pool(std::size_t num_threads);
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 template <typename Allocator>
0128 thread_pool(allocator_arg_t, const Allocator& a, std::size_t num_threads);
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 BOOST_ASIO_DECL thread_pool(std::size_t num_threads,
0141 const execution_context::service_maker& initial_services);
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 template <typename Allocator>
0158 thread_pool(allocator_arg_t, const Allocator& a, std::size_t num_threads,
0159 const execution_context::service_maker& initial_services);
0160
0161
0162
0163
0164
0165 BOOST_ASIO_DECL ~thread_pool();
0166
0167
0168 executor_type get_executor() noexcept;
0169
0170
0171 executor_type executor() noexcept;
0172
0173
0174
0175
0176
0177
0178 BOOST_ASIO_DECL void stop();
0179
0180
0181
0182
0183
0184
0185
0186 BOOST_ASIO_DECL void attach();
0187
0188
0189
0190
0191
0192
0193
0194 BOOST_ASIO_DECL void join();
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 BOOST_ASIO_DECL void wait();
0205
0206 private:
0207 thread_pool(const thread_pool&) = delete;
0208 thread_pool& operator=(const thread_pool&) = delete;
0209
0210 struct thread_function;
0211
0212 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
0213
0214 BOOST_ASIO_DECL static long default_thread_pool_size();
0215 #endif
0216
0217
0218 BOOST_ASIO_DECL static long clamp_thread_pool_size(std::size_t n);
0219
0220
0221 BOOST_ASIO_DECL void start();
0222
0223
0224 detail::scheduler& scheduler_;
0225
0226
0227 detail::thread_group<allocator<void>> threads_;
0228
0229
0230 detail::atomic_count num_threads_;
0231
0232
0233 bool joinable_;
0234 };
0235
0236
0237 template <typename Allocator, unsigned int Bits>
0238 class thread_pool::basic_executor_type : detail::thread_pool_bits
0239 {
0240 public:
0241
0242 basic_executor_type(const basic_executor_type& other) noexcept
0243 : pool_(other.pool_),
0244 allocator_(other.allocator_),
0245 bits_(other.bits_)
0246 {
0247 if (Bits & outstanding_work_tracked)
0248 if (pool_)
0249 pool_->scheduler_.work_started();
0250 }
0251
0252
0253 basic_executor_type(basic_executor_type&& other) noexcept
0254 : pool_(other.pool_),
0255 allocator_(static_cast<Allocator&&>(other.allocator_)),
0256 bits_(other.bits_)
0257 {
0258 if (Bits & outstanding_work_tracked)
0259 other.pool_ = 0;
0260 }
0261
0262
0263 ~basic_executor_type() noexcept
0264 {
0265 if (Bits & outstanding_work_tracked)
0266 if (pool_)
0267 pool_->scheduler_.work_finished();
0268 }
0269
0270
0271 basic_executor_type& operator=(const basic_executor_type& other) noexcept;
0272
0273
0274 basic_executor_type& operator=(basic_executor_type&& other) noexcept;
0275
0276 #if !defined(GENERATING_DOCUMENTATION)
0277 private:
0278 friend struct boost_asio_require_fn::impl;
0279 friend struct boost_asio_prefer_fn::impl;
0280 #endif
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 constexpr basic_executor_type<Allocator,
0293 BOOST_ASIO_UNSPECIFIED(Bits & ~blocking_mask)>
0294 require(execution::blocking_t::possibly_t) const
0295 {
0296 return basic_executor_type<Allocator, Bits & ~blocking_mask>(
0297 pool_, allocator_, bits_ & ~blocking_mask);
0298 }
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310 constexpr basic_executor_type<Allocator,
0311 BOOST_ASIO_UNSPECIFIED((Bits & ~blocking_mask) | blocking_always)>
0312 require(execution::blocking_t::always_t) const
0313 {
0314 return basic_executor_type<Allocator,
0315 BOOST_ASIO_UNSPECIFIED((Bits & ~blocking_mask) | blocking_always)>(
0316 pool_, allocator_, bits_ & ~blocking_mask);
0317 }
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 constexpr basic_executor_type<Allocator,
0330 BOOST_ASIO_UNSPECIFIED(Bits & ~blocking_mask)>
0331 require(execution::blocking_t::never_t) const
0332 {
0333 return basic_executor_type<Allocator, Bits & ~blocking_mask>(
0334 pool_, allocator_, (bits_ & ~blocking_mask) | blocking_never);
0335 }
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 constexpr basic_executor_type require(execution::relationship_t::fork_t) const
0348 {
0349 return basic_executor_type(pool_,
0350 allocator_, bits_ & ~relationship_continuation);
0351 }
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363 constexpr basic_executor_type require(
0364 execution::relationship_t::continuation_t) const
0365 {
0366 return basic_executor_type(pool_,
0367 allocator_, bits_ | relationship_continuation);
0368 }
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 constexpr basic_executor_type<Allocator,
0381 BOOST_ASIO_UNSPECIFIED(Bits | outstanding_work_tracked)>
0382 require(execution::outstanding_work_t::tracked_t) const
0383 {
0384 return basic_executor_type<Allocator, Bits | outstanding_work_tracked>(
0385 pool_, allocator_, bits_);
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 constexpr basic_executor_type<Allocator,
0399 BOOST_ASIO_UNSPECIFIED(Bits & ~outstanding_work_tracked)>
0400 require(execution::outstanding_work_t::untracked_t) const
0401 {
0402 return basic_executor_type<Allocator, Bits & ~outstanding_work_tracked>(
0403 pool_, allocator_, bits_);
0404 }
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416 template <typename OtherAllocator>
0417 constexpr basic_executor_type<OtherAllocator, Bits>
0418 require(execution::allocator_t<OtherAllocator> a) const
0419 {
0420 return basic_executor_type<OtherAllocator, Bits>(
0421 pool_, a.value(), bits_);
0422 }
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434 constexpr basic_executor_type<std::allocator<void>, Bits>
0435 require(execution::allocator_t<void>) const
0436 {
0437 return basic_executor_type<std::allocator<void>, Bits>(
0438 pool_, std::allocator<void>(), bits_);
0439 }
0440
0441 #if !defined(GENERATING_DOCUMENTATION)
0442 private:
0443 friend struct boost_asio_query_fn::impl;
0444 friend struct boost::asio::execution::detail::mapping_t<0>;
0445 friend struct boost::asio::execution::detail::inline_exception_handling_t<0>;
0446 friend struct boost::asio::execution::detail::outstanding_work_t<0>;
0447 #endif
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460 static constexpr execution::mapping_t query(execution::mapping_t) noexcept
0461 {
0462 return execution::mapping.thread;
0463 }
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 static constexpr execution::inline_exception_handling_t query(
0478 execution::inline_exception_handling_t) noexcept
0479 {
0480 return execution::inline_exception_handling.terminate;
0481 }
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 thread_pool& query(execution::context_t) const noexcept
0494 {
0495 return *pool_;
0496 }
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509 constexpr execution::blocking_t query(execution::blocking_t) const noexcept
0510 {
0511 return (bits_ & blocking_never)
0512 ? execution::blocking_t(execution::blocking.never)
0513 : ((Bits & blocking_always)
0514 ? execution::blocking_t(execution::blocking.always)
0515 : execution::blocking_t(execution::blocking.possibly));
0516 }
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529 constexpr execution::relationship_t query(
0530 execution::relationship_t) const noexcept
0531 {
0532 return (bits_ & relationship_continuation)
0533 ? execution::relationship_t(execution::relationship.continuation)
0534 : execution::relationship_t(execution::relationship.fork);
0535 }
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548 static constexpr execution::outstanding_work_t query(
0549 execution::outstanding_work_t) noexcept
0550 {
0551 return (Bits & outstanding_work_tracked)
0552 ? execution::outstanding_work_t(execution::outstanding_work.tracked)
0553 : execution::outstanding_work_t(execution::outstanding_work.untracked);
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566 template <typename OtherAllocator>
0567 constexpr Allocator query(
0568 execution::allocator_t<OtherAllocator>) const noexcept
0569 {
0570 return allocator_;
0571 }
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 constexpr Allocator query(execution::allocator_t<void>) const noexcept
0584 {
0585 return allocator_;
0586 }
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598 std::size_t query(execution::occupancy_t) const noexcept
0599 {
0600 return static_cast<std::size_t>(pool_->num_threads_);
0601 }
0602
0603 public:
0604
0605
0606
0607
0608
0609 bool running_in_this_thread() const noexcept;
0610
0611
0612
0613
0614
0615 friend bool operator==(const basic_executor_type& a,
0616 const basic_executor_type& b) noexcept
0617 {
0618 return a.pool_ == b.pool_
0619 && a.allocator_ == b.allocator_
0620 && a.bits_ == b.bits_;
0621 }
0622
0623
0624
0625
0626
0627 friend bool operator!=(const basic_executor_type& a,
0628 const basic_executor_type& b) noexcept
0629 {
0630 return a.pool_ != b.pool_
0631 || a.allocator_ != b.allocator_
0632 || a.bits_ != b.bits_;
0633 }
0634
0635
0636 template <typename Function>
0637 void execute(Function&& f) const
0638 {
0639 this->do_execute(static_cast<Function&&>(f),
0640 integral_constant<bool, (Bits & blocking_always) != 0>());
0641 }
0642
0643 public:
0644 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
0645
0646 thread_pool& context() const noexcept;
0647
0648
0649
0650
0651
0652
0653
0654 void on_work_started() const noexcept;
0655
0656
0657
0658
0659
0660
0661
0662 void on_work_finished() const noexcept;
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678 template <typename Function, typename OtherAllocator>
0679 void dispatch(Function&& f, const OtherAllocator& a) const;
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694 template <typename Function, typename OtherAllocator>
0695 void post(Function&& f, const OtherAllocator& a) const;
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714 template <typename Function, typename OtherAllocator>
0715 void defer(Function&& f, const OtherAllocator& a) const;
0716 #endif
0717
0718 private:
0719 friend class thread_pool;
0720 template <typename, unsigned int> friend class basic_executor_type;
0721
0722
0723 explicit basic_executor_type(thread_pool& p) noexcept
0724 : pool_(&p),
0725 allocator_(),
0726 bits_(0)
0727 {
0728 if (Bits & outstanding_work_tracked)
0729 pool_->scheduler_.work_started();
0730 }
0731
0732
0733 basic_executor_type(thread_pool* p,
0734 const Allocator& a, unsigned int bits) noexcept
0735 : pool_(p),
0736 allocator_(a),
0737 bits_(bits)
0738 {
0739 if (Bits & outstanding_work_tracked)
0740 if (pool_)
0741 pool_->scheduler_.work_started();
0742 }
0743
0744
0745 template <typename Function>
0746 void do_execute(Function&& f, false_type) const;
0747
0748
0749 template <typename Function>
0750 void do_execute(Function&& f, true_type) const;
0751
0752
0753 thread_pool* pool_;
0754
0755
0756 Allocator allocator_;
0757
0758
0759 unsigned int bits_;
0760 };
0761
0762 #if !defined(GENERATING_DOCUMENTATION)
0763
0764 namespace traits {
0765
0766 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
0767
0768 template <typename Allocator, unsigned int Bits>
0769 struct equality_comparable<
0770 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>
0771 >
0772 {
0773 static constexpr bool is_valid = true;
0774 static constexpr bool is_noexcept = true;
0775 };
0776
0777 #endif
0778
0779 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
0780
0781 template <typename Allocator, unsigned int Bits, typename Function>
0782 struct execute_member<
0783 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0784 Function
0785 >
0786 {
0787 static constexpr bool is_valid = true;
0788 static constexpr bool is_noexcept = false;
0789 typedef void result_type;
0790 };
0791
0792 #endif
0793
0794 #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
0795
0796 template <typename Allocator, unsigned int Bits>
0797 struct require_member<
0798 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0799 boost::asio::execution::blocking_t::possibly_t
0800 > : boost::asio::detail::thread_pool_bits
0801 {
0802 static constexpr bool is_valid = true;
0803 static constexpr bool is_noexcept = true;
0804 typedef boost::asio::thread_pool::basic_executor_type<
0805 Allocator, Bits & ~blocking_mask> result_type;
0806 };
0807
0808 template <typename Allocator, unsigned int Bits>
0809 struct require_member<
0810 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0811 boost::asio::execution::blocking_t::always_t
0812 > : boost::asio::detail::thread_pool_bits
0813 {
0814 static constexpr bool is_valid = true;
0815 static constexpr bool is_noexcept = false;
0816 typedef boost::asio::thread_pool::basic_executor_type<Allocator,
0817 (Bits & ~blocking_mask) | blocking_always> result_type;
0818 };
0819
0820 template <typename Allocator, unsigned int Bits>
0821 struct require_member<
0822 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0823 boost::asio::execution::blocking_t::never_t
0824 > : boost::asio::detail::thread_pool_bits
0825 {
0826 static constexpr bool is_valid = true;
0827 static constexpr bool is_noexcept = false;
0828 typedef boost::asio::thread_pool::basic_executor_type<
0829 Allocator, Bits & ~blocking_mask> result_type;
0830 };
0831
0832 template <typename Allocator, unsigned int Bits>
0833 struct require_member<
0834 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0835 boost::asio::execution::relationship_t::fork_t
0836 >
0837 {
0838 static constexpr bool is_valid = true;
0839 static constexpr bool is_noexcept = false;
0840 typedef boost::asio::thread_pool::basic_executor_type<
0841 Allocator, Bits> result_type;
0842 };
0843
0844 template <typename Allocator, unsigned int Bits>
0845 struct require_member<
0846 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0847 boost::asio::execution::relationship_t::continuation_t
0848 >
0849 {
0850 static constexpr bool is_valid = true;
0851 static constexpr bool is_noexcept = false;
0852 typedef boost::asio::thread_pool::basic_executor_type<
0853 Allocator, Bits> result_type;
0854 };
0855
0856 template <typename Allocator, unsigned int Bits>
0857 struct require_member<
0858 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0859 boost::asio::execution::outstanding_work_t::tracked_t
0860 > : boost::asio::detail::thread_pool_bits
0861 {
0862 static constexpr bool is_valid = true;
0863 static constexpr bool is_noexcept = false;
0864 typedef boost::asio::thread_pool::basic_executor_type<
0865 Allocator, Bits | outstanding_work_tracked> result_type;
0866 };
0867
0868 template <typename Allocator, unsigned int Bits>
0869 struct require_member<
0870 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0871 boost::asio::execution::outstanding_work_t::untracked_t
0872 > : boost::asio::detail::thread_pool_bits
0873 {
0874 static constexpr bool is_valid = true;
0875 static constexpr bool is_noexcept = false;
0876 typedef boost::asio::thread_pool::basic_executor_type<
0877 Allocator, Bits & ~outstanding_work_tracked> result_type;
0878 };
0879
0880 template <typename Allocator, unsigned int Bits>
0881 struct require_member<
0882 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0883 boost::asio::execution::allocator_t<void>
0884 >
0885 {
0886 static constexpr bool is_valid = true;
0887 static constexpr bool is_noexcept = false;
0888 typedef boost::asio::thread_pool::basic_executor_type<
0889 std::allocator<void>, Bits> result_type;
0890 };
0891
0892 template <unsigned int Bits,
0893 typename Allocator, typename OtherAllocator>
0894 struct require_member<
0895 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0896 boost::asio::execution::allocator_t<OtherAllocator>
0897 >
0898 {
0899 static constexpr bool is_valid = true;
0900 static constexpr bool is_noexcept = false;
0901 typedef boost::asio::thread_pool::basic_executor_type<
0902 OtherAllocator, Bits> result_type;
0903 };
0904
0905 #endif
0906
0907 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
0908
0909 template <typename Allocator, unsigned int Bits, typename Property>
0910 struct query_static_constexpr_member<
0911 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0912 Property,
0913 typename boost::asio::enable_if<
0914 boost::asio::is_convertible<
0915 Property,
0916 boost::asio::execution::outstanding_work_t
0917 >::value
0918 >::type
0919 > : boost::asio::detail::thread_pool_bits
0920 {
0921 static constexpr bool is_valid = true;
0922 static constexpr bool is_noexcept = true;
0923 typedef boost::asio::execution::outstanding_work_t result_type;
0924
0925 static constexpr result_type value() noexcept
0926 {
0927 return (Bits & outstanding_work_tracked)
0928 ? execution::outstanding_work_t(execution::outstanding_work.tracked)
0929 : execution::outstanding_work_t(execution::outstanding_work.untracked);
0930 }
0931 };
0932
0933 template <typename Allocator, unsigned int Bits, typename Property>
0934 struct query_static_constexpr_member<
0935 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0936 Property,
0937 typename boost::asio::enable_if<
0938 boost::asio::is_convertible<
0939 Property,
0940 boost::asio::execution::mapping_t
0941 >::value
0942 >::type
0943 >
0944 {
0945 static constexpr bool is_valid = true;
0946 static constexpr bool is_noexcept = true;
0947 typedef boost::asio::execution::mapping_t::thread_t result_type;
0948
0949 static constexpr result_type value() noexcept
0950 {
0951 return result_type();
0952 }
0953 };
0954
0955 template <typename Allocator, unsigned int Bits, typename Property>
0956 struct query_static_constexpr_member<
0957 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0958 Property,
0959 typename boost::asio::enable_if<
0960 boost::asio::is_convertible<
0961 Property,
0962 boost::asio::execution::inline_exception_handling_t
0963 >::value
0964 >::type
0965 >
0966 {
0967 static constexpr bool is_valid = true;
0968 static constexpr bool is_noexcept = true;
0969 typedef boost::asio::execution::inline_exception_handling_t::terminate_t
0970 result_type;
0971
0972 static constexpr result_type value() noexcept
0973 {
0974 return result_type();
0975 }
0976 };
0977
0978 #endif
0979
0980 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
0981
0982 template <typename Allocator, unsigned int Bits, typename Property>
0983 struct query_member<
0984 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
0985 Property,
0986 typename boost::asio::enable_if<
0987 boost::asio::is_convertible<
0988 Property,
0989 boost::asio::execution::blocking_t
0990 >::value
0991 >::type
0992 >
0993 {
0994 static constexpr bool is_valid = true;
0995 static constexpr bool is_noexcept = true;
0996 typedef boost::asio::execution::blocking_t result_type;
0997 };
0998
0999 template <typename Allocator, unsigned int Bits, typename Property>
1000 struct query_member<
1001 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
1002 Property,
1003 typename boost::asio::enable_if<
1004 boost::asio::is_convertible<
1005 Property,
1006 boost::asio::execution::relationship_t
1007 >::value
1008 >::type
1009 >
1010 {
1011 static constexpr bool is_valid = true;
1012 static constexpr bool is_noexcept = true;
1013 typedef boost::asio::execution::relationship_t result_type;
1014 };
1015
1016 template <typename Allocator, unsigned int Bits>
1017 struct query_member<
1018 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
1019 boost::asio::execution::occupancy_t
1020 >
1021 {
1022 static constexpr bool is_valid = true;
1023 static constexpr bool is_noexcept = true;
1024 typedef std::size_t result_type;
1025 };
1026
1027 template <typename Allocator, unsigned int Bits>
1028 struct query_member<
1029 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
1030 boost::asio::execution::context_t
1031 >
1032 {
1033 static constexpr bool is_valid = true;
1034 static constexpr bool is_noexcept = true;
1035 typedef boost::asio::thread_pool& result_type;
1036 };
1037
1038 template <typename Allocator, unsigned int Bits>
1039 struct query_member<
1040 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
1041 boost::asio::execution::allocator_t<void>
1042 >
1043 {
1044 static constexpr bool is_valid = true;
1045 static constexpr bool is_noexcept = true;
1046 typedef Allocator result_type;
1047 };
1048
1049 template <typename Allocator, unsigned int Bits, typename OtherAllocator>
1050 struct query_member<
1051 boost::asio::thread_pool::basic_executor_type<Allocator, Bits>,
1052 boost::asio::execution::allocator_t<OtherAllocator>
1053 >
1054 {
1055 static constexpr bool is_valid = true;
1056 static constexpr bool is_noexcept = true;
1057 typedef Allocator result_type;
1058 };
1059
1060 #endif
1061
1062 }
1063
1064 namespace execution {
1065
1066 template <>
1067 struct is_executor<thread_pool> : false_type
1068 {
1069 };
1070
1071 }
1072
1073 #endif
1074
1075 }
1076 }
1077
1078 #include <boost/asio/detail/pop_options.hpp>
1079
1080 #include <boost/asio/impl/thread_pool.hpp>
1081 #if defined(BOOST_ASIO_HEADER_ONLY)
1082 # include <boost/asio/impl/thread_pool.ipp>
1083 #endif
1084
1085 #endif