#include "waked.h"

#include <util/thread/singleton.h>

namespace {
inline NSrvKernel::TThreadLocalEventWaker*& ThisThreadWaker() {
    struct TThisThreadWakerHolder {
        NSrvKernel::TThreadLocalEventWaker* Waker = nullptr;
    };
    return FastTlsSingletonWithPriority<TThisThreadWakerHolder, 0>()->Waker;
}
}

namespace NSrvKernel {
    TThreadLocalEventWaker::TThreadLocalEventWaker(TContExecutor* executor)
        : TEventWaker(executor)
    {
        ThisThreadWaker() = this;
    }

    TThreadLocalEventWaker::~TThreadLocalEventWaker(){
        ThisThreadWaker() = nullptr;
    }

    using TThreadLocalEventWakerRef = TIntrusivePtr<TThreadLocalEventWaker>;

    TThreadLocalEventWakerRef ThreadLocalEventWaker(TCont* cont) {
        TContExecutor* currentExecutor = cont->Executor();
        if (ThisThreadWaker() && currentExecutor == ThisThreadWaker()->Executor()) {
            return {ThisThreadWaker()};
        }

        return MakeIntrusive<TThreadLocalEventWaker>(currentExecutor);
    }

    TThreadLocalEventWakerRef ThreadLocalEventWaker() {
        if (TCont* running = RunningCont()) {
            return ThreadLocalEventWaker(running);
        } else {
            return nullptr;
        }
    }
}
