annotate DEPENDENCIES/generic/include/boost/thread/scoped_thread.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 2 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 3 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 4 // (C) Copyright 2009-2012 Anthony Williams
Chris@16 5 // (C) Copyright 2012 Vicente J. Botet Escriba
Chris@16 6
Chris@16 7 // Based on the Anthony's idea of scoped_thread in CCiA
Chris@16 8
Chris@16 9 #ifndef BOOST_THREAD_SCOPED_THREAD_HPP
Chris@16 10 #define BOOST_THREAD_SCOPED_THREAD_HPP
Chris@16 11
Chris@16 12 #include <boost/thread/detail/config.hpp>
Chris@16 13 #include <boost/thread/detail/delete.hpp>
Chris@16 14 #include <boost/thread/detail/move.hpp>
Chris@16 15 #include <boost/thread/thread_functors.hpp>
Chris@16 16 #include <boost/thread/thread_only.hpp>
Chris@16 17
Chris@16 18 #include <boost/config/abi_prefix.hpp>
Chris@16 19
Chris@16 20 namespace boost
Chris@16 21 {
Chris@16 22
Chris@16 23 /**
Chris@16 24 * RAI @c thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
Chris@16 25 *
Chris@16 26 * CallableThread: A callable void(thread&) .
Chris@16 27 * The default is a join_if_joinable.
Chris@16 28 *
Chris@16 29 * thread std/boost::thread destructor terminates the program if the thread is not joinable.
Chris@16 30 * Having a wrapper that can join the thread before destroying it seems a natural need.
Chris@16 31 *
Chris@16 32 * Example:
Chris@16 33 *
Chris@16 34 * boost::strict_scoped_thread<> t((boost::thread(F)));
Chris@16 35 *
Chris@16 36 */
Chris@16 37 template <class CallableThread = join_if_joinable>
Chris@16 38 class strict_scoped_thread
Chris@16 39 {
Chris@16 40 thread t_;
Chris@16 41 struct dummy;
Chris@16 42 public:
Chris@16 43
Chris@16 44 BOOST_THREAD_NO_COPYABLE( strict_scoped_thread) /// non copyable
Chris@16 45
Chris@16 46 /*
Chris@16 47 *
Chris@16 48 */
Chris@16 49 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@101 50 template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type>
Chris@16 51 explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
Chris@16 52 t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
Chris@16 53 #else
Chris@16 54 template <class F>
Chris@16 55 explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f,
Chris@101 56 typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type=0) :
Chris@16 57 t_(boost::forward<F>(f)) {}
Chris@16 58 template <class F, class A1>
Chris@16 59 strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
Chris@16 60 t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
Chris@16 61 template <class F, class A1, class A2>
Chris@16 62 strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
Chris@16 63 t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
Chris@16 64 template <class F, class A1, class A2, class A3>
Chris@16 65 strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
Chris@16 66 t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
Chris@16 67 #endif
Chris@16 68
Chris@16 69 /**
Chris@16 70 * Constructor from the thread to own.
Chris@16 71 *
Chris@16 72 * @param t: the thread to own.
Chris@16 73 *
Chris@16 74 * Effects: move the thread to own @c t.
Chris@16 75 */
Chris@16 76 explicit strict_scoped_thread(BOOST_THREAD_RV_REF(thread) t) BOOST_NOEXCEPT :
Chris@16 77 t_(boost::move(t))
Chris@16 78 {
Chris@16 79 }
Chris@16 80
Chris@16 81 /**
Chris@16 82 * Destructor
Chris@16 83 * Effects: Call the CallableThread functor before destroying the owned thread.
Chris@16 84 * Remark: The CallableThread should not throw when joining the thread as the scoped variable is on a scope outside the thread function.
Chris@16 85 */
Chris@16 86 ~strict_scoped_thread()
Chris@16 87 {
Chris@16 88 CallableThread on_destructor;
Chris@16 89
Chris@16 90 on_destructor(t_);
Chris@16 91 }
Chris@16 92
Chris@16 93 };
Chris@16 94
Chris@16 95 /**
Chris@16 96 * RAI @c thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
Chris@16 97 *
Chris@16 98 * CallableThread: A callable void(thread&) .
Chris@16 99 * The default is join_if_joinable.
Chris@16 100 *
Chris@16 101 * thread std::thread destructor terminates the program if the thread is not joinable.
Chris@16 102 * Having a wrapper that can join the thread before destroying it seems a natural need.
Chris@16 103 *
Chris@16 104 * Remark: @c scoped_thread is not a @c thread as @c thread is not designed to be derived from as a polymorphic type.
Chris@16 105 * Anyway @c scoped_thread can be used in most of the contexts a @c thread could be used as it has the
Chris@16 106 * same non-deprecated interface with the exception of the construction.
Chris@16 107 *
Chris@16 108 * Example:
Chris@16 109 *
Chris@16 110 * boost::scoped_thread<> t((boost::thread(F)));
Chris@16 111 * t.interrupt();
Chris@16 112 *
Chris@16 113 */
Chris@16 114 template <class CallableThread = join_if_joinable>
Chris@16 115 class scoped_thread
Chris@16 116 {
Chris@16 117 thread t_;
Chris@16 118 struct dummy;
Chris@16 119 public:
Chris@16 120
Chris@16 121 typedef thread::id id;
Chris@16 122
Chris@16 123 BOOST_THREAD_MOVABLE_ONLY( scoped_thread) /// Movable only
Chris@16 124
Chris@16 125 /**
Chris@16 126 * Default Constructor.
Chris@16 127 *
Chris@16 128 * Effects: wraps a not-a-thread.
Chris@16 129 */
Chris@16 130 scoped_thread() BOOST_NOEXCEPT:
Chris@16 131 t_()
Chris@16 132 {
Chris@16 133 }
Chris@16 134
Chris@16 135 /**
Chris@16 136 *
Chris@16 137 */
Chris@16 138
Chris@16 139 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@101 140 template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type>
Chris@16 141 explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
Chris@16 142 t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
Chris@16 143 #else
Chris@16 144 template <class F>
Chris@16 145 explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f,
Chris@101 146 typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type=0) :
Chris@16 147 t_(boost::forward<F>(f)) {}
Chris@16 148 template <class F, class A1>
Chris@16 149 scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
Chris@16 150 t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
Chris@16 151 template <class F, class A1, class A2>
Chris@16 152 scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
Chris@16 153 t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
Chris@16 154 template <class F, class A1, class A2, class A3>
Chris@16 155 scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
Chris@16 156 t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
Chris@16 157
Chris@16 158 #endif
Chris@16 159 /**
Chris@16 160 * Constructor from the thread to own.
Chris@16 161 *
Chris@16 162 * @param t: the thread to own.
Chris@16 163 *
Chris@16 164 * Effects: move the thread to own @c t.
Chris@16 165 */
Chris@16 166 explicit scoped_thread(BOOST_THREAD_RV_REF(thread) t) BOOST_NOEXCEPT :
Chris@16 167 t_(boost::move(t))
Chris@16 168 {
Chris@16 169 }
Chris@16 170
Chris@16 171 // explicit operator thread()
Chris@16 172 // {
Chris@16 173 // return boost::move(t_);
Chris@16 174 // }
Chris@16 175
Chris@16 176 /**
Chris@16 177 * Move constructor.
Chris@16 178 */
Chris@16 179 scoped_thread(BOOST_RV_REF(scoped_thread) x) BOOST_NOEXCEPT :
Chris@101 180 t_(boost::move(BOOST_THREAD_RV(x).t_))
Chris@16 181 {}
Chris@16 182
Chris@16 183 /**
Chris@16 184 * Destructor
Chris@16 185 *
Chris@16 186 * Effects: Call the CallableThread functor before destroying the owned thread.
Chris@16 187 */
Chris@16 188 ~scoped_thread()
Chris@16 189 {
Chris@16 190 CallableThread on_destructor;
Chris@16 191
Chris@16 192 on_destructor(t_);
Chris@16 193 }
Chris@16 194
Chris@16 195 /**
Chris@16 196 * Move assignment.
Chris@16 197 */
Chris@16 198 scoped_thread& operator=(BOOST_RV_REF(scoped_thread) x)
Chris@16 199 {
Chris@101 200 t_ = boost::move(BOOST_THREAD_RV(x).t_);
Chris@16 201 return *this;
Chris@16 202 }
Chris@16 203
Chris@16 204 /**
Chris@16 205 *
Chris@16 206 */
Chris@16 207 void swap(scoped_thread& x) BOOST_NOEXCEPT
Chris@16 208 {
Chris@16 209 t_.swap(x.t_);
Chris@16 210 }
Chris@16 211
Chris@16 212 // forwarded thread functions
Chris@16 213 inline thread::id get_id() const BOOST_NOEXCEPT
Chris@16 214 {
Chris@16 215 return t_.get_id();
Chris@16 216 }
Chris@16 217
Chris@16 218 void detach()
Chris@16 219 {
Chris@16 220 t_.detach();
Chris@16 221 }
Chris@16 222
Chris@16 223 void join()
Chris@16 224 {
Chris@16 225 t_.join();
Chris@16 226 }
Chris@16 227
Chris@16 228 #ifdef BOOST_THREAD_USES_CHRONO
Chris@16 229 template <class Rep, class Period>
Chris@16 230 bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
Chris@16 231 {
Chris@16 232 return t_.try_join_for(rel_time);
Chris@16 233 }
Chris@16 234
Chris@16 235 template <class Clock, class Duration>
Chris@16 236 bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time)
Chris@16 237 {
Chris@16 238 return t_.try_join_until(abs_time);
Chris@16 239 }
Chris@16 240 #endif
Chris@16 241
Chris@16 242 thread::native_handle_type native_handle()BOOST_NOEXCEPT
Chris@16 243 {
Chris@16 244 return t_.native_handle();
Chris@16 245 }
Chris@16 246
Chris@16 247 bool joinable() const BOOST_NOEXCEPT
Chris@16 248 {
Chris@16 249 return t_.joinable();
Chris@16 250 }
Chris@16 251
Chris@16 252 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
Chris@16 253 void interrupt()
Chris@16 254 {
Chris@16 255 t_.interrupt();
Chris@16 256 }
Chris@16 257
Chris@16 258 bool interruption_requested() const BOOST_NOEXCEPT
Chris@16 259 {
Chris@16 260 return t_.interruption_requested();
Chris@16 261 }
Chris@16 262 #endif
Chris@16 263
Chris@101 264 static unsigned hardware_concurrency() BOOST_NOEXCEPT
Chris@16 265 {
Chris@16 266 return thread::hardware_concurrency();
Chris@16 267 }
Chris@16 268
Chris@101 269 #ifdef BOOST_THREAD_PROVIDES_PHYSICAL_CONCURRENCY
Chris@101 270 static unsigned physical_concurrency() BOOST_NOEXCEPT
Chris@101 271 {
Chris@101 272 return thread::physical_concurrency();
Chris@101 273 }
Chris@101 274 #endif
Chris@16 275 };
Chris@16 276
Chris@16 277 /**
Chris@16 278 * Effects: swaps the contents of two scoped threads.
Chris@16 279 */
Chris@16 280 template <class Destroyer>
Chris@16 281 void swap(scoped_thread<Destroyer>& lhs, scoped_thread<Destroyer>& rhs)
Chris@16 282 BOOST_NOEXCEPT {
Chris@16 283 return lhs.swap(rhs);
Chris@16 284 }
Chris@16 285
Chris@16 286 }
Chris@16 287 #include <boost/config/abi_suffix.hpp>
Chris@16 288
Chris@16 289 #endif