1
2#include "boost/fiber/waker.hpp"
3#include "boost/fiber/context.hpp"
4
5namespace boost {
6namespace fibers {
7
8bool
9waker::wake() const noexcept {
10 BOOST_ASSERT(epoch_ > 0);
11 BOOST_ASSERT(ctx_ != nullptr);
12
13 return ctx_->wake(epoch_);
14}
15
16void
17wait_queue::suspend_and_wait( detail::spinlock_lock & lk, context * active_ctx) {
18 waker_with_hook w{ active_ctx->create_waker() };
19 slist_.push_back(value&: w);
20 // suspend this fiber
21 active_ctx->suspend( lk);
22 BOOST_ASSERT( ! w.is_linked() );
23}
24
25bool
26wait_queue::suspend_and_wait_until( detail::spinlock_lock & lk,
27 context * active_ctx,
28 std::chrono::steady_clock::time_point const& timeout_time) {
29 waker_with_hook w{ active_ctx->create_waker() };
30 slist_.push_back(value&: w);
31 // suspend this fiber
32 if ( ! active_ctx->wait_until( timeout_time, lk, waker(w)) ) {
33 // relock local lk
34 for(;;) {
35 if(lk.try_lock())
36 break;
37 active_ctx->yield();
38 }
39 // remove from waiting-queue
40 if ( w.is_linked()) {
41 slist_.remove( value: w);
42 }
43 lk.unlock();
44 return false;
45 }
46 return true;
47}
48
49void
50wait_queue::notify_one() {
51 while ( ! slist_.empty() ) {
52 waker & w = slist_.front();
53 slist_.pop_front();
54 if ( w.wake()) {
55 break;
56 }
57 }
58}
59
60void
61wait_queue::notify_all() {
62 while ( ! slist_.empty() ) {
63 waker & w = slist_.front();
64 slist_.pop_front();
65 w.wake();
66 }
67}
68
69bool
70wait_queue::empty() const {
71 return slist_.empty();
72}
73
74}
75}
76

source code of boost/libs/fiber/src/waker.cpp