aboutsummaryrefslogblamecommitdiffstats
path: root/library/cpp/coroutine/engine/events.h
blob: 07cc4d25e87e4177ae40325d897c36d93ab08137 (plain) (tree)
1
2
3
4
5
6
7
8
9



                               
 
                  
                                       



                        
                   
     
                                  




                                                
                                  

                                           
                 

                                      
                          


                            
                            

                     
                                 

                       
                                         









                                                                          
                                        


                                 
                    


         
                               
     
                       
                                   
     
                                                  





                                      
                                                  

                                                    
                               

                                               
                            


                                        
 
                               



                                        
                                            
                                                                  


                                        


                                     
 
                        
                                      


               
                                              

                  
                            

                    
                               

                       
                                                 
     
                                           

                                           
                          





                                      
#pragma once

#include "impl.h"

#include <util/datetime/base.h>

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<TWaiter> {
    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<TWaiter> 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_;
};