Warning, file /include/boost/thread/experimental/parallel/v2/task_region.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_TASK_REGION_HPP
0002 #define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_TASK_REGION_HPP
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <exception>
0015 #include <boost/throw_exception.hpp>
0016 #include <boost/thread/detail/config.hpp>
0017
0018 #include <boost/thread/future.hpp>
0019 #if defined BOOST_THREAD_PROVIDES_EXECUTORS
0020 #include <boost/thread/executors/basic_thread_pool.hpp>
0021 #endif
0022 #include <boost/thread/experimental/exception_list.hpp>
0023 #include <boost/thread/experimental/parallel/v2/inline_namespace.hpp>
0024 #include <boost/thread/csbl/vector.hpp>
0025 #include <boost/thread/detail/move.hpp>
0026
0027 #include <boost/config/abi_prefix.hpp>
0028
0029 #define BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
0030
0031 namespace boost
0032 {
0033 namespace experimental
0034 {
0035 namespace parallel
0036 {
0037 BOOST_THREAD_INLINE_NAMESPACE(v2)
0038 {
0039 class BOOST_SYMBOL_VISIBLE task_canceled_exception: public std::exception
0040 {
0041 public:
0042
0043
0044
0045 virtual const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
0046 { return "task_canceled_exception";}
0047 };
0048
0049 template <class Executor>
0050 class task_region_handle_gen;
0051
0052 namespace detail
0053 {
0054 void handle_task_region_exceptions(exception_list& errors)
0055 {
0056 try {
0057 throw;
0058 }
0059 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
0060 catch (task_canceled_exception&)
0061 {
0062 }
0063 #endif
0064 catch (exception_list const& el)
0065 {
0066 for (exception_list::const_iterator it = el.begin(); it != el.end(); ++it)
0067 {
0068 boost::exception_ptr const& e = *it;
0069 try {
0070 rethrow_exception(e);
0071 }
0072 catch (...)
0073 {
0074 handle_task_region_exceptions(errors);
0075 }
0076 }
0077 }
0078 catch (...)
0079 {
0080 errors.add(boost::current_exception());
0081 }
0082 }
0083
0084 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
0085 template <class TRH, class F>
0086 struct wrapped
0087 {
0088 TRH& tr;
0089 F f;
0090 wrapped(TRH& tr, BOOST_THREAD_RV_REF(F) f) : tr(tr), f(move(f))
0091 {}
0092 void operator()()
0093 {
0094 try
0095 {
0096 f();
0097 }
0098 catch (...)
0099 {
0100 lock_guard<mutex> lk(tr.mtx);
0101 tr.canceled = true;
0102 throw;
0103 }
0104 }
0105 };
0106 #endif
0107 }
0108
0109 template <class Executor>
0110 class task_region_handle_gen
0111 {
0112 private:
0113
0114 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
0115 template <class TRH, class F>
0116 friend struct detail::wrapped;
0117 #endif
0118 template <typename F>
0119 friend void task_region(BOOST_THREAD_FWD_REF(F) f);
0120 template<typename F>
0121 friend void task_region_final(BOOST_THREAD_FWD_REF(F) f);
0122 template <class Ex, typename F>
0123 friend void task_region(Ex&, BOOST_THREAD_FWD_REF(F) f);
0124 template<class Ex, typename F>
0125 friend void task_region_final(Ex&, BOOST_THREAD_FWD_REF(F) f);
0126
0127 void wait_all()
0128 {
0129 wait_for_all(group.begin(), group.end());
0130
0131 for (group_type::iterator it = group.begin(); it != group.end(); ++it)
0132 {
0133 BOOST_THREAD_FUTURE<void>& f = *it;
0134 if (f.has_exception())
0135 {
0136 try
0137 {
0138 boost::rethrow_exception(f.get_exception_ptr());
0139 }
0140 catch (...)
0141 {
0142 detail::handle_task_region_exceptions(exs);
0143 }
0144 }
0145 }
0146 if (exs.size() != 0)
0147 {
0148 boost::throw_exception(exs);
0149 }
0150 }
0151 protected:
0152 #if ! defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && ! defined BOOST_THREAD_PROVIDES_EXECUTORS
0153 task_region_handle_gen()
0154 {}
0155 #endif
0156
0157 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && defined BOOST_THREAD_PROVIDES_EXECUTORS
0158 task_region_handle_gen()
0159 : canceled(false)
0160 , ex(0)
0161 {}
0162 task_region_handle_gen(Executor& ex)
0163 : canceled(false)
0164 , ex(&ex)
0165 {}
0166
0167 #endif
0168
0169 #if ! defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && defined BOOST_THREAD_PROVIDES_EXECUTORS
0170 task_region_handle_gen()
0171 : ex(0)
0172 {}
0173 task_region_handle_gen(Executor& ex)
0174 : ex(&ex)
0175 {}
0176 #endif
0177
0178 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && ! defined BOOST_THREAD_PROVIDES_EXECUTORS
0179 task_region_handle_gen()
0180 : canceled(false)
0181 {
0182 }
0183 #endif
0184
0185 ~task_region_handle_gen()
0186 {
0187
0188 }
0189
0190 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
0191 mutable mutex mtx;
0192 bool canceled;
0193 #endif
0194 #if defined BOOST_THREAD_PROVIDES_EXECUTORS
0195 Executor* ex;
0196 #endif
0197 exception_list exs;
0198 typedef csbl::vector<BOOST_THREAD_FUTURE<void> > group_type;
0199 group_type group;
0200
0201 public:
0202 BOOST_DELETED_FUNCTION(task_region_handle_gen(const task_region_handle_gen&))
0203 BOOST_DELETED_FUNCTION(task_region_handle_gen& operator=(const task_region_handle_gen&))
0204 BOOST_DELETED_FUNCTION(task_region_handle_gen* operator&() const)
0205
0206 public:
0207 template<typename F>
0208 void run(BOOST_THREAD_FWD_REF(F) f)
0209 {
0210 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
0211 {
0212 lock_guard<mutex> lk(mtx);
0213 if (canceled) {
0214 boost::throw_exception(task_canceled_exception());
0215 }
0216 }
0217 #if defined BOOST_THREAD_PROVIDES_EXECUTORS
0218 group.push_back(async(*ex, detail::wrapped<task_region_handle_gen<Executor>, F>(*this, forward<F>(f))));
0219 #else
0220 group.push_back(async(detail::wrapped<task_region_handle_gen<Executor>, F>(*this, forward<F>(f))));
0221 #endif
0222 #else
0223 #if defined BOOST_THREAD_PROVIDES_EXECUTORS
0224 group.push_back(async(*ex, forward<F>(f)));
0225 #else
0226 group.push_back(async(forward<F>(f)));
0227 #endif
0228 #endif
0229 }
0230
0231 void wait()
0232 {
0233 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
0234 {
0235 lock_guard<mutex> lk(mtx);
0236 if (canceled) {
0237 boost::throw_exception(task_canceled_exception());
0238 }
0239 }
0240 #endif
0241 wait_all();
0242 }
0243 };
0244 #if defined BOOST_THREAD_PROVIDES_EXECUTORS
0245 typedef basic_thread_pool default_executor;
0246 #else
0247 typedef int default_executor;
0248 #endif
0249 class task_region_handle :
0250 public task_region_handle_gen<default_executor>
0251 {
0252 default_executor tp;
0253 template <typename F>
0254 friend void task_region(BOOST_THREAD_FWD_REF(F) f);
0255 template<typename F>
0256 friend void task_region_final(BOOST_THREAD_FWD_REF(F) f);
0257
0258 protected:
0259 task_region_handle() : task_region_handle_gen<default_executor>()
0260 {
0261 #if defined BOOST_THREAD_PROVIDES_EXECUTORS
0262 ex = &tp;
0263 #endif
0264 }
0265 BOOST_DELETED_FUNCTION(task_region_handle(const task_region_handle&))
0266 BOOST_DELETED_FUNCTION(task_region_handle& operator=(const task_region_handle&))
0267 BOOST_DELETED_FUNCTION(task_region_handle* operator&() const)
0268
0269 };
0270
0271 template <typename Executor, typename F>
0272 void task_region_final(Executor& ex, BOOST_THREAD_FWD_REF(F) f)
0273 {
0274 task_region_handle_gen<Executor> tr(ex);
0275 try
0276 {
0277 f(tr);
0278 }
0279 catch (...)
0280 {
0281 detail::handle_task_region_exceptions(tr.exs);
0282 }
0283 tr.wait_all();
0284 }
0285
0286 template <typename Executor, typename F>
0287 void task_region(Executor& ex, BOOST_THREAD_FWD_REF(F) f)
0288 {
0289 task_region_final(ex, forward<F>(f));
0290 }
0291
0292 template <typename F>
0293 void task_region_final(BOOST_THREAD_FWD_REF(F) f)
0294 {
0295 task_region_handle tr;
0296 try
0297 {
0298 f(tr);
0299 }
0300 catch (...)
0301 {
0302 detail::handle_task_region_exceptions(tr.exs);
0303 }
0304 tr.wait_all();
0305 }
0306
0307 template <typename F>
0308 void task_region(BOOST_THREAD_FWD_REF(F) f)
0309 {
0310 task_region_final(forward<F>(f));
0311 }
0312
0313 }
0314 }
0315 }
0316 }
0317
0318 #include <boost/config/abi_suffix.hpp>
0319
0320 #endif