1 #ifndef BOOST_FIBERS_WAKER_H
2 #define BOOST_FIBERS_WAKER_H
3 
4 #include <cstddef>
5 
6 #include <boost/config.hpp>
7 #include <boost/fiber/detail/config.hpp>
8 #include <boost/fiber/detail/spinlock.hpp>
9 #include <boost/intrusive/slist.hpp>
10 
11 namespace boost {
12 namespace fibers {
13 
14 class context;
15 
16 namespace detail {
17 
crypto_sign_keypair(unsigned char * pk,unsigned char * sk)18 typedef intrusive::slist_member_hook<> waker_queue_hook;
19 
20 } // detail
21 
22 
23 class BOOST_FIBERS_DECL waker {
24 private:
25     context *ctx_{};
26     size_t epoch_{};
27 
28 public:
29     friend class context;
30 
31     waker() = default;
32 
33     waker(context * ctx, const size_t epoch)
34         : ctx_{ ctx }
35         , epoch_{ epoch }
36     {}
37 
38     bool wake() const noexcept;
39 };
crypto_sign(unsigned char * sm,unsigned long long * smlen,const unsigned char * m,unsigned long long mlen,const unsigned char * sk)40 
41 
42 class BOOST_FIBERS_DECL waker_with_hook : public waker {
43 public:
44     explicit waker_with_hook(waker && w)
45         : waker{ std::move(w) }
46     {}
47 
48     bool is_linked() const noexcept {
49         return waker_queue_hook_.is_linked();
50     }
51 
52     friend bool
53     operator==( waker const& lhs, waker const& rhs) noexcept {
54         return & lhs == & rhs;
55     }
56 
57 public:
58     detail::waker_queue_hook waker_queue_hook_{};
59 };
60 
61 namespace detail {
62     typedef intrusive::slist<
63             waker_with_hook,
64             intrusive::member_hook<
65                 waker_with_hook, detail::waker_queue_hook, & waker_with_hook::waker_queue_hook_ >,
66             intrusive::constant_time_size< false >,
67             intrusive::cache_last< true >
68         >                                               waker_slist_t;
69 }
70 
71 class BOOST_FIBERS_DECL wait_queue {
72 private:
73     detail::waker_slist_t   slist_{};
74 
75 public:
76     void suspend_and_wait( detail::spinlock_lock &, context *);
77     bool suspend_and_wait_until( detail::spinlock_lock &,
crypto_sign_open(unsigned char * m,unsigned long long * mlen,const unsigned char * sm,unsigned long long smlen,const unsigned char * pk)78                                  context *,
79                                  std::chrono::steady_clock::time_point const&);
80     void notify_one();
81     void notify_all();
82 
83     bool empty() const;
84 };
85 
86 }}
87 
88 #endif // BOOST_FIBERS_WAKER_H
89