#pragma once #include #include #include #include #include namespace NThreading { class TAsyncSemaphore: public TThrRefBase { public: using TPtr = TIntrusivePtr; class TAutoRelease { public: TAutoRelease(TAsyncSemaphore::TPtr sem) : Sem(std::move(sem)) { } TAutoRelease(TAutoRelease&& other) : Sem(std::move(other.Sem)) { } ~TAutoRelease(); std::function&)> DeferRelease(); private: TAsyncSemaphore::TPtr Sem; }; static TPtr Make(size_t count); TFuture AcquireAsync(); void Release(); void Cancel(); TAutoRelease MakeAutoRelease() { return {this}; } private: TAsyncSemaphore(size_t count); private: size_t Count_; bool Cancelled_ = false; TAdaptiveLock Lock_; std::list> Promises_; }; } // namespace NThreading