The C and C++ Include Header Files
/usr/include/c++/11/condition_variable
$ cat -n /usr/include/c++/11/condition_variable 1 //
-*- C++ -*- 2 3 // Copyright (C) 2008-2021 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 24 25 /** @file include/condition_variable 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_CONDITION_VARIABLE 30 #define _GLIBCXX_CONDITION_VARIABLE 1 31 32 #pragma GCC system_header 33 34 #if __cplusplus < 201103L 35 # include
36 #else 37 38 #include
39 40 #include
41 #include
42 #include
43 #include
44 #include
45 46 #if __cplusplus > 201703L 47 # include
48 #endif 49 50 #if defined(_GLIBCXX_HAS_GTHREADS) 51 52 namespace std _GLIBCXX_VISIBILITY(default) 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 /** 57 * @defgroup condition_variables Condition Variables 58 * @ingroup concurrency 59 * 60 * Classes for condition_variable support. 61 * @{ 62 */ 63 64 /// cv_status 65 enum class cv_status { no_timeout, timeout }; 66 67 /// condition_variable 68 class condition_variable 69 { 70 using steady_clock = chrono::steady_clock; 71 using system_clock = chrono::system_clock; 72 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT 73 using __clock_t = steady_clock; 74 #else 75 using __clock_t = system_clock; 76 #endif 77 78 __condvar _M_cond; 79 80 public: 81 typedef __gthread_cond_t* native_handle_type; 82 83 condition_variable() noexcept; 84 ~condition_variable() noexcept; 85 86 condition_variable(const condition_variable&) = delete; 87 condition_variable& operator=(const condition_variable&) = delete; 88 89 void 90 notify_one() noexcept; 91 92 void 93 notify_all() noexcept; 94 95 void 96 wait(unique_lock
& __lock) noexcept; 97 98 template
99 void 100 wait(unique_lock
& __lock, _Predicate __p) 101 { 102 while (!__p()) 103 wait(__lock); 104 } 105 106 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT 107 template
108 cv_status 109 wait_until(unique_lock
& __lock, 110 const chrono::time_point
& __atime) 111 { return __wait_until_impl(__lock, __atime); } 112 #endif 113 114 template
115 cv_status 116 wait_until(unique_lock
& __lock, 117 const chrono::time_point
& __atime) 118 { return __wait_until_impl(__lock, __atime); } 119 120 template
121 cv_status 122 wait_until(unique_lock
& __lock, 123 const chrono::time_point<_Clock, _Duration>& __atime) 124 { 125 #if __cplusplus > 201703L 126 static_assert(chrono::is_clock_v<_Clock>); 127 #endif 128 using __s_dur = typename __clock_t::duration; 129 const typename _Clock::time_point __c_entry = _Clock::now(); 130 const __clock_t::time_point __s_entry = __clock_t::now(); 131 const auto __delta = __atime - __c_entry; 132 const auto __s_atime = __s_entry + 133 chrono::__detail::ceil<__s_dur>(__delta); 134 135 if (__wait_until_impl(__lock, __s_atime) == cv_status::no_timeout) 136 return cv_status::no_timeout; 137 // We got a timeout when measured against __clock_t but 138 // we need to check against the caller-supplied clock 139 // to tell whether we should return a timeout. 140 if (_Clock::now() < __atime) 141 return cv_status::no_timeout; 142 return cv_status::timeout; 143 } 144 145 template
146 bool 147 wait_until(unique_lock
& __lock, 148 const chrono::time_point<_Clock, _Duration>& __atime, 149 _Predicate __p) 150 { 151 while (!__p()) 152 if (wait_until(__lock, __atime) == cv_status::timeout) 153 return __p(); 154 return true; 155 } 156 157 template
158 cv_status 159 wait_for(unique_lock
& __lock, 160 const chrono::duration<_Rep, _Period>& __rtime) 161 { 162 using __dur = typename steady_clock::duration; 163 return wait_until(__lock, 164 steady_clock::now() + 165 chrono::__detail::ceil<__dur>(__rtime)); 166 } 167 168 template
169 bool 170 wait_for(unique_lock
& __lock, 171 const chrono::duration<_Rep, _Period>& __rtime, 172 _Predicate __p) 173 { 174 using __dur = typename steady_clock::duration; 175 return wait_until(__lock, 176 steady_clock::now() + 177 chrono::__detail::ceil<__dur>(__rtime), 178 std::move(__p)); 179 } 180 181 native_handle_type 182 native_handle() 183 { return _M_cond.native_handle(); } 184 185 private: 186 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT 187 template
188 cv_status 189 __wait_until_impl(unique_lock
& __lock, 190 const chrono::time_point
& __atime) 191 { 192 auto __s = chrono::time_point_cast
(__atime); 193 auto __ns = chrono::duration_cast
(__atime - __s); 194 195 __gthread_time_t __ts = 196 { 197 static_cast
(__s.time_since_epoch().count()), 198 static_cast
(__ns.count()) 199 }; 200 201 _M_cond.wait_until(*__lock.mutex(), CLOCK_MONOTONIC, __ts); 202 203 return (steady_clock::now() < __atime 204 ? cv_status::no_timeout : cv_status::timeout); 205 } 206 #endif 207 208 template
209 cv_status 210 __wait_until_impl(unique_lock
& __lock, 211 const chrono::time_point
& __atime) 212 { 213 auto __s = chrono::time_point_cast
(__atime); 214 auto __ns = chrono::duration_cast
(__atime - __s); 215 216 __gthread_time_t __ts = 217 { 218 static_cast
(__s.time_since_epoch().count()), 219 static_cast
(__ns.count()) 220 }; 221 222 _M_cond.wait_until(*__lock.mutex(), __ts); 223 224 return (system_clock::now() < __atime 225 ? cv_status::no_timeout : cv_status::timeout); 226 } 227 }; 228 229 void 230 notify_all_at_thread_exit(condition_variable&, unique_lock
); 231 232 struct __at_thread_exit_elt 233 { 234 __at_thread_exit_elt* _M_next; 235 void (*_M_cb)(void*); 236 }; 237 238 inline namespace _V2 { 239 240 /// condition_variable_any 241 // Like above, but mutex is not required to have try_lock. 242 class condition_variable_any 243 { 244 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT 245 using __clock_t = chrono::steady_clock; 246 #else 247 using __clock_t = chrono::system_clock; 248 #endif 249 condition_variable _M_cond; 250 shared_ptr
_M_mutex; 251 252 // scoped unlock - unlocks in ctor, re-locks in dtor 253 template
254 struct _Unlock 255 { 256 explicit _Unlock(_Lock& __lk) : _M_lock(__lk) { __lk.unlock(); } 257 258 #pragma GCC diagnostic push 259 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 260 ~_Unlock() noexcept(false) 261 { 262 if (uncaught_exception()) 263 { 264 __try 265 { _M_lock.lock(); } 266 __catch(const __cxxabiv1::__forced_unwind&) 267 { __throw_exception_again; } 268 __catch(...) 269 { } 270 } 271 else 272 _M_lock.lock(); 273 } 274 #pragma GCC diagnostic pop 275 276 _Unlock(const _Unlock&) = delete; 277 _Unlock& operator=(const _Unlock&) = delete; 278 279 _Lock& _M_lock; 280 }; 281 282 public: 283 condition_variable_any() : _M_mutex(std::make_shared
()) { } 284 ~condition_variable_any() = default; 285 286 condition_variable_any(const condition_variable_any&) = delete; 287 condition_variable_any& operator=(const condition_variable_any&) = delete; 288 289 void 290 notify_one() noexcept 291 { 292 lock_guard
__lock(*_M_mutex); 293 _M_cond.notify_one(); 294 } 295 296 void 297 notify_all() noexcept 298 { 299 lock_guard
__lock(*_M_mutex); 300 _M_cond.notify_all(); 301 } 302 303 template
304 void 305 wait(_Lock& __lock) 306 { 307 shared_ptr
__mutex = _M_mutex; 308 unique_lock
__my_lock(*__mutex); 309 _Unlock<_Lock> __unlock(__lock); 310 // *__mutex must be unlocked before re-locking __lock so move 311 // ownership of *__mutex lock to an object with shorter lifetime. 312 unique_lock
__my_lock2(std::move(__my_lock)); 313 _M_cond.wait(__my_lock2); 314 } 315 316 317 template
318 void 319 wait(_Lock& __lock, _Predicate __p) 320 { 321 while (!__p()) 322 wait(__lock); 323 } 324 325 template
326 cv_status 327 wait_until(_Lock& __lock, 328 const chrono::time_point<_Clock, _Duration>& __atime) 329 { 330 shared_ptr
__mutex = _M_mutex; 331 unique_lock
__my_lock(*__mutex); 332 _Unlock<_Lock> __unlock(__lock); 333 // *__mutex must be unlocked before re-locking __lock so move 334 // ownership of *__mutex lock to an object with shorter lifetime. 335 unique_lock
__my_lock2(std::move(__my_lock)); 336 return _M_cond.wait_until(__my_lock2, __atime); 337 } 338 339 template
341 bool 342 wait_until(_Lock& __lock, 343 const chrono::time_point<_Clock, _Duration>& __atime, 344 _Predicate __p) 345 { 346 while (!__p()) 347 if (wait_until(__lock, __atime) == cv_status::timeout) 348 return __p(); 349 return true; 350 } 351 352 template
353 cv_status 354 wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime) 355 { return wait_until(__lock, __clock_t::now() + __rtime); } 356 357 template
359 bool 360 wait_for(_Lock& __lock, 361 const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) 362 { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); } 363 364 #ifdef __cpp_lib_jthread 365 template
366 bool wait(_Lock& __lock, 367 stop_token __stoken, 368 _Predicate __p) 369 { 370 if (__stoken.stop_requested()) 371 { 372 return __p(); 373 } 374 375 std::stop_callback __cb(__stoken, [this] { notify_all(); }); 376 shared_ptr
__mutex = _M_mutex; 377 while (!__p()) 378 { 379 unique_lock
__my_lock(*__mutex); 380 if (__stoken.stop_requested()) 381 { 382 return false; 383 } 384 // *__mutex must be unlocked before re-locking __lock so move 385 // ownership of *__mutex lock to an object with shorter lifetime. 386 _Unlock<_Lock> __unlock(__lock); 387 unique_lock
__my_lock2(std::move(__my_lock)); 388 _M_cond.wait(__my_lock2); 389 } 390 return true; 391 } 392 393 template
394 bool wait_until(_Lock& __lock, 395 stop_token __stoken, 396 const chrono::time_point<_Clock, _Duration>& __abs_time, 397 _Predicate __p) 398 { 399 if (__stoken.stop_requested()) 400 { 401 return __p(); 402 } 403 404 std::stop_callback __cb(__stoken, [this] { notify_all(); }); 405 shared_ptr
__mutex = _M_mutex; 406 while (!__p()) 407 { 408 bool __stop; 409 { 410 unique_lock
__my_lock(*__mutex); 411 if (__stoken.stop_requested()) 412 { 413 return false; 414 } 415 _Unlock<_Lock> __u(__lock); 416 unique_lock
__my_lock2(std::move(__my_lock)); 417 const auto __status = _M_cond.wait_until(__my_lock2, __abs_time); 418 __stop = (__status == std::cv_status::timeout) || __stoken.stop_requested(); 419 } 420 if (__stop) 421 { 422 return __p(); 423 } 424 } 425 return true; 426 } 427 428 template
429 bool wait_for(_Lock& __lock, 430 stop_token __stoken, 431 const chrono::duration<_Rep, _Period>& __rel_time, 432 _Predicate __p) 433 { 434 auto __abst = std::chrono::steady_clock::now() + __rel_time; 435 return wait_until(__lock, 436 std::move(__stoken), 437 __abst, 438 std::move(__p)); 439 } 440 #endif 441 }; 442 443 } // end inline namespace 444 445 /// @} group condition_variables 446 _GLIBCXX_END_NAMESPACE_VERSION 447 } // namespace 448 449 #endif // _GLIBCXX_HAS_GTHREADS 450 #endif // C++11 451 #endif // _GLIBCXX_CONDITION_VARIABLE
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™