events.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #pragma once
  2. #include "impl.h"
  3. #include <util/datetime/base.h>
  4. class TContEvent {
  5. public:
  6. TContEvent(TCont* current) noexcept
  7. : Cont_(current)
  8. , Status_(0)
  9. {
  10. }
  11. ~TContEvent() {
  12. }
  13. int WaitD(TInstant deadline) {
  14. Status_ = 0;
  15. const int ret = Cont_->SleepD(deadline);
  16. return Status_ ? Status_ : ret;
  17. }
  18. int WaitT(TDuration timeout) {
  19. return WaitD(timeout.ToDeadLine());
  20. }
  21. int WaitI() {
  22. return WaitD(TInstant::Max());
  23. }
  24. void Wake() noexcept {
  25. SetStatus(EWAKEDUP);
  26. Cont_->ReSchedule();
  27. }
  28. TCont* Cont() noexcept {
  29. return Cont_;
  30. }
  31. int Status() const noexcept {
  32. return Status_;
  33. }
  34. void SetStatus(int status) noexcept {
  35. Status_ = status;
  36. }
  37. private:
  38. TCont* Cont_;
  39. int Status_;
  40. };
  41. class TContWaitQueue {
  42. class TWaiter: public TContEvent, public TIntrusiveListItem<TWaiter> {
  43. public:
  44. TWaiter(TCont* current) noexcept
  45. : TContEvent(current)
  46. {
  47. }
  48. ~TWaiter() {
  49. }
  50. };
  51. public:
  52. TContWaitQueue() noexcept {
  53. }
  54. ~TContWaitQueue() {
  55. Y_ASSERT(Waiters_.Empty());
  56. }
  57. int WaitD(TCont* current, TInstant deadline) {
  58. TWaiter waiter(current);
  59. Waiters_.PushBack(&waiter);
  60. return waiter.WaitD(deadline);
  61. }
  62. int WaitT(TCont* current, TDuration timeout) {
  63. return WaitD(current, timeout.ToDeadLine());
  64. }
  65. int WaitI(TCont* current) {
  66. return WaitD(current, TInstant::Max());
  67. }
  68. void Signal() noexcept {
  69. if (!Waiters_.Empty()) {
  70. Waiters_.PopFront()->Wake();
  71. }
  72. }
  73. void BroadCast() noexcept {
  74. while (!Waiters_.Empty()) {
  75. Waiters_.PopFront()->Wake();
  76. }
  77. }
  78. void BroadCast(size_t number) noexcept {
  79. for (size_t i = 0; i < number && !Waiters_.Empty(); ++i) {
  80. Waiters_.PopFront()->Wake();
  81. }
  82. }
  83. private:
  84. TIntrusiveList<TWaiter> Waiters_;
  85. };
  86. class TContSimpleEvent {
  87. public:
  88. TContSimpleEvent(TContExecutor* e)
  89. : E_(e)
  90. {
  91. }
  92. TContExecutor* Executor() const noexcept {
  93. return E_;
  94. }
  95. void Signal() noexcept {
  96. Q_.Signal();
  97. }
  98. void BroadCast() noexcept {
  99. Q_.BroadCast();
  100. }
  101. int WaitD(TInstant deadLine) noexcept {
  102. return Q_.WaitD(E_->Running(), deadLine);
  103. }
  104. int WaitT(TDuration timeout) noexcept {
  105. return WaitD(timeout.ToDeadLine());
  106. }
  107. int WaitI() noexcept {
  108. return WaitD(TInstant::Max());
  109. }
  110. private:
  111. TContWaitQueue Q_;
  112. TContExecutor* E_;
  113. };