File indexing completed on 2025-01-30 10:01:11
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_THREAD_SERIAL_EXECUTOR_CONT_HPP
0010 #define BOOST_THREAD_SERIAL_EXECUTOR_CONT_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 <exception> // std::terminate
0016 #include <boost/throw_exception.hpp>
0017 #include <boost/thread/detail/delete.hpp>
0018 #include <boost/thread/detail/move.hpp>
0019 #include <boost/thread/concurrent_queues/sync_queue.hpp>
0020 #include <boost/thread/executors/work.hpp>
0021 #include <boost/thread/executors/generic_executor_ref.hpp>
0022 #include <boost/thread/mutex.hpp>
0023 #include <boost/thread/future.hpp>
0024 #include <boost/thread/scoped_thread.hpp>
0025 #include <boost/thread/lock_guard.hpp>
0026
0027 #include <boost/config/abi_prefix.hpp>
0028
0029 namespace boost
0030 {
0031 namespace executors
0032 {
0033 class serial_executor_cont
0034 {
0035 public:
0036
0037 typedef executors::work work;
0038 private:
0039
0040 generic_executor_ref ex_;
0041 BOOST_THREAD_FUTURE<void> fut_;
0042 bool closed_;
0043 mutex mtx_;
0044
0045 struct continuation {
0046 work task;
0047 template <class X>
0048 struct result {
0049 typedef void type;
0050 };
0051 continuation(BOOST_THREAD_RV_REF(work) tsk)
0052 : task(boost::move(tsk)) {}
0053 void operator()(BOOST_THREAD_FUTURE<void> f)
0054 {
0055 try {
0056 task();
0057 } catch (...) {
0058 std::terminate();
0059 }
0060 }
0061 };
0062
0063 bool closed(lock_guard<mutex>&) const
0064 {
0065 return closed_;
0066 }
0067 public:
0068
0069
0070
0071
0072 generic_executor_ref& underlying_executor() BOOST_NOEXCEPT { return ex_; }
0073
0074
0075 BOOST_THREAD_NO_COPYABLE(serial_executor_cont)
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 template <class Executor>
0089 serial_executor_cont(Executor& ex)
0090 : ex_(ex), fut_(make_ready_future()), closed_(false)
0091 {
0092 }
0093
0094
0095
0096
0097
0098 ~serial_executor_cont()
0099 {
0100
0101 close();
0102 }
0103
0104
0105
0106
0107
0108 void close()
0109 {
0110 lock_guard<mutex> lk(mtx_);
0111 closed_ = true;;
0112 }
0113
0114
0115
0116
0117 bool closed()
0118 {
0119 lock_guard<mutex> lk(mtx_);
0120 return closed(lk);
0121 }
0122
0123
0124
0125
0126
0127
0128
0129 bool try_executing_one()
0130 {
0131 return false;
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0146 template <typename Closure>
0147 void submit(Closure & closure)
0148 {
0149 lock_guard<mutex> lk(mtx_);
0150 if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0151 fut_ = fut_.then(ex_, continuation(work(closure)));
0152 }
0153 #endif
0154 void submit(void (*closure)())
0155 {
0156 lock_guard<mutex> lk(mtx_);
0157 if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0158 fut_ = fut_.then(ex_, continuation(work(closure)));
0159 }
0160
0161 template <typename Closure>
0162 void submit(BOOST_THREAD_FWD_REF(Closure) closure)
0163 {
0164 lock_guard<mutex> lk(mtx_);
0165 if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0166 fut_ = fut_.then(ex_, continuation(work(boost::forward<Closure>(closure))));
0167 }
0168
0169 };
0170 }
0171 using executors::serial_executor_cont;
0172 }
0173
0174 #include <boost/config/abi_suffix.hpp>
0175
0176 #endif
0177 #endif