#pragma once #include "impl.h" #include class TContEvent { public: TContEvent(TCont* current) noexcept : Cont_(current) , Status_(0) { } ~TContEvent() { } int WaitD(TInstant deadline) { Status_ = 0; const int ret = Cont_->SleepD(deadline); return Status_ ? Status_ : ret; } int WaitT(TDuration timeout) { return WaitD(timeout.ToDeadLine()); } int WaitI() { return WaitD(TInstant::Max()); } void Wake() noexcept { SetStatus(EWAKEDUP); Cont_->ReSchedule(); } TCont* Cont() noexcept { return Cont_; } int Status() const noexcept { return Status_; } void SetStatus(int status) noexcept { Status_ = status; } private: TCont* Cont_; int Status_; }; class TContWaitQueue { class TWaiter: public TContEvent, public TIntrusiveListItem { public: TWaiter(TCont* current) noexcept : TContEvent(current) { } ~TWaiter() { } }; public: TContWaitQueue() noexcept { } ~TContWaitQueue() { Y_ASSERT(Waiters_.Empty()); } int WaitD(TCont* current, TInstant deadline) { TWaiter waiter(current); Waiters_.PushBack(&waiter); return waiter.WaitD(deadline); } int WaitT(TCont* current, TDuration timeout) { return WaitD(current, timeout.ToDeadLine()); } int WaitI(TCont* current) { return WaitD(current, TInstant::Max()); } void Signal() noexcept { if (!Waiters_.Empty()) { Waiters_.PopFront()->Wake(); } } void BroadCast() noexcept { while (!Waiters_.Empty()) { Waiters_.PopFront()->Wake(); } } void BroadCast(size_t number) noexcept { for (size_t i = 0; i < number && !Waiters_.Empty(); ++i) { Waiters_.PopFront()->Wake(); } } private: TIntrusiveList Waiters_; }; class TContSimpleEvent { public: TContSimpleEvent(TContExecutor* e) : E_(e) { } TContExecutor* Executor() const noexcept { return E_; } void Signal() noexcept { Q_.Signal(); } void BroadCast() noexcept { Q_.BroadCast(); } int WaitD(TInstant deadLine) noexcept { return Q_.WaitD(E_->Running(), deadLine); } int WaitT(TDuration timeout) noexcept { return WaitD(timeout.ToDeadLine()); } int WaitI() noexcept { return WaitD(TInstant::Max()); } private: TContWaitQueue Q_; TContExecutor* E_; };