File indexing completed on 2025-12-15 10:09:32
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_THREAD_USER_SCHEDULER_HPP
0010 #define BOOST_THREAD_USER_SCHEDULER_HPP
0011
0012 #include <boost/thread/detail/config.hpp>
0013 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
0014
0015 #include <boost/thread/detail/delete.hpp>
0016 #include <boost/thread/detail/move.hpp>
0017 #include <boost/thread/concurrent_queues/sync_queue.hpp>
0018 #include <boost/thread/executors/work.hpp>
0019
0020 #include <boost/config/abi_prefix.hpp>
0021
0022 namespace boost
0023 {
0024
0025 class user_scheduler
0026 {
0027
0028 typedef executors::work work;
0029
0030
0031 sync_queue<work > work_queue;
0032
0033 public:
0034
0035
0036
0037
0038
0039 bool try_executing_one()
0040 {
0041 work task;
0042 try
0043 {
0044 if (work_queue.try_pull(task) == queue_op_status::success)
0045 {
0046 task();
0047 return true;
0048 }
0049 return false;
0050 }
0051 catch (std::exception& )
0052 {
0053 return false;
0054 }
0055 catch (...)
0056 {
0057 return false;
0058 }
0059 }
0060 private:
0061
0062
0063
0064
0065 void schedule_one_or_yield()
0066 {
0067 if ( ! try_executing_one())
0068 {
0069 this_thread::yield();
0070 }
0071 }
0072
0073
0074
0075
0076
0077 void worker_thread()
0078 {
0079 while (!closed())
0080 {
0081 schedule_one_or_yield();
0082 }
0083 while (try_executing_one())
0084 {
0085 }
0086 }
0087
0088 public:
0089
0090 BOOST_THREAD_NO_COPYABLE(user_scheduler)
0091
0092
0093
0094
0095
0096
0097 user_scheduler()
0098 {
0099 }
0100
0101
0102
0103
0104
0105 ~user_scheduler()
0106 {
0107
0108 close();
0109 }
0110
0111
0112
0113
0114 void loop() { worker_thread(); }
0115
0116
0117
0118
0119 void close()
0120 {
0121 work_queue.close();
0122 }
0123
0124
0125
0126
0127 bool closed()
0128 {
0129 return work_queue.closed();
0130 }
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0145 template <typename Closure>
0146 void submit(Closure & closure)
0147 {
0148 work w ((closure));
0149 work_queue.push(boost::move(w));
0150
0151 }
0152 #endif
0153 void submit(void (*closure)())
0154 {
0155 work w ((closure));
0156 work_queue.push(boost::move(w));
0157
0158 }
0159
0160 template <typename Closure>
0161 void submit(BOOST_THREAD_RV_REF(Closure) closure)
0162 {
0163 work w =boost::move(closure);
0164 work_queue.push(boost::move(w));
0165
0166 }
0167
0168
0169
0170
0171
0172
0173 template <typename Pred>
0174 bool reschedule_until(Pred const& pred)
0175 {
0176 do {
0177 if ( ! try_executing_one())
0178 {
0179 return false;
0180 }
0181 } while (! pred());
0182 return true;
0183 }
0184
0185
0186
0187 void run_queued_closures()
0188 {
0189 sync_queue<work>::underlying_queue_type q = work_queue.underlying_queue();
0190 while (q.empty())
0191 {
0192 work task = q.front();
0193 q.pop_front();
0194 task();
0195 }
0196 }
0197
0198 };
0199
0200 }
0201
0202 #include <boost/config/abi_suffix.hpp>
0203
0204 #endif
0205 #endif