waker.hpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #ifndef BOOST_FIBERS_WAKER_H
  2. #define BOOST_FIBERS_WAKER_H
  3. #include <cstddef>
  4. #include <boost/config.hpp>
  5. #include <boost/fiber/detail/config.hpp>
  6. #include <boost/fiber/detail/spinlock.hpp>
  7. #include <boost/intrusive/slist.hpp>
  8. namespace boost {
  9. namespace fibers {
  10. class context;
  11. namespace detail {
  12. typedef intrusive::slist_member_hook<> waker_queue_hook;
  13. } // detail
  14. class BOOST_FIBERS_DECL waker {
  15. private:
  16. context *ctx_{};
  17. size_t epoch_{};
  18. public:
  19. friend class context;
  20. waker() = default;
  21. waker(context * ctx, const size_t epoch)
  22. : ctx_{ ctx }
  23. , epoch_{ epoch }
  24. {}
  25. bool wake() const noexcept;
  26. };
  27. class BOOST_FIBERS_DECL waker_with_hook : public waker {
  28. public:
  29. explicit waker_with_hook(waker && w)
  30. : waker{ std::move(w) }
  31. {}
  32. bool is_linked() const noexcept {
  33. return waker_queue_hook_.is_linked();
  34. }
  35. friend bool
  36. operator==( waker const& lhs, waker const& rhs) noexcept {
  37. return & lhs == & rhs;
  38. }
  39. public:
  40. detail::waker_queue_hook waker_queue_hook_{};
  41. };
  42. namespace detail {
  43. typedef intrusive::slist<
  44. waker_with_hook,
  45. intrusive::member_hook<
  46. waker_with_hook, detail::waker_queue_hook, & waker_with_hook::waker_queue_hook_ >,
  47. intrusive::constant_time_size< false >,
  48. intrusive::cache_last< true >
  49. > waker_slist_t;
  50. }
  51. class BOOST_FIBERS_DECL wait_queue {
  52. private:
  53. detail::waker_slist_t slist_{};
  54. public:
  55. void suspend_and_wait( detail::spinlock_lock &, context *);
  56. bool suspend_and_wait_until( detail::spinlock_lock &,
  57. context *,
  58. std::chrono::steady_clock::time_point const&);
  59. void notify_one();
  60. void notify_all();
  61. bool empty() const;
  62. };
  63. }}
  64. #endif // BOOST_FIBERS_WAKER_H