123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #pragma once
- #include "fwd.h"
- #include <library/cpp/messagebus/actor/actor.h>
- #include <library/cpp/messagebus/misc/atomic_box.h>
- #include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
- #include <util/generic/noncopyable.h>
- #include <util/generic/ptr.h>
- #include <util/thread/lfstack.h>
- namespace NRainCheck {
- struct ISubtaskListener {
- virtual void SetDone() = 0;
- virtual ~ISubtaskListener() {
- }
- };
- struct TNopSubtaskListener: public ISubtaskListener {
- void SetDone() override;
- static TNopSubtaskListener Instance;
- };
- class TSubtaskCompletionFunc {
- friend class TSubtaskCompletion;
- typedef void (ITaskBase::*TFunc)(TSubtaskCompletion*);
- TFunc Func;
- public:
- TSubtaskCompletionFunc()
- : Func(nullptr)
- {
- }
- TSubtaskCompletionFunc(void*)
- : Func(nullptr)
- {
- }
- template <typename TTask>
- TSubtaskCompletionFunc(void (TTask::*func)(TSubtaskCompletion*))
- : Func((TFunc)func)
- {
- static_assert((std::is_base_of<ITaskBase, TTask>::value), "expect (std::is_base_of<ITaskBase, TTask>::value)");
- }
- bool operator!() const {
- return !Func;
- }
- };
- template <typename T>
- class TTaskFuture;
- #define SUBTASK_STATE_MAP(XX) \
- XX(CREATED, "Initial") \
- XX(RUNNING, "Running") \
- XX(DONE, "Completed") \
- XX(CANCEL_REQUESTED, "Cancel requested, but still executing") \
- XX(CANCELED, "Canceled") \
- /**/
- enum ESubtaskState {
- SUBTASK_STATE_MAP(ENUM_VALUE_GEN_NO_VALUE)
- };
- ENUM_TO_STRING(ESubtaskState, SUBTASK_STATE_MAP)
- class TSubtaskCompletion : TNonCopyable, public ISubtaskListener {
- friend struct TTaskAccessor;
- private:
- TAtomicBox<ESubtaskState> State;
- TTaskRunnerBase* volatile TaskRunner;
- TSubtaskCompletionFunc CompletionFunc;
- public:
- TSubtaskCompletion()
- : State(CREATED)
- , TaskRunner()
- {
- }
- ~TSubtaskCompletion() override;
- // Either done or cancel requested or cancelled
- bool IsComplete() const {
- ESubtaskState state = State.Get();
- switch (state) {
- case RUNNING:
- return false;
- case DONE:
- return true;
- case CANCEL_REQUESTED:
- return false;
- case CANCELED:
- return true;
- case CREATED:
- Y_ABORT("not started");
- default:
- Y_ABORT("unknown value: %u", (unsigned)state);
- }
- }
- void FireCompletionCallback(ITaskBase*);
- void SetCompletionCallback(TSubtaskCompletionFunc func) {
- CompletionFunc = func;
- }
- // Completed, but not cancelled
- bool IsDone() const {
- return State.Get() == DONE;
- }
- // Request cancel by actor
- // Does nothing but marks task cancelled,
- // and allows proceeding to next callback
- void Cancel();
- // called by service provider implementations
- // must not be called by actor
- void SetRunning(TTaskRunnerBase* parent);
- void SetDone() override;
- };
- // See ISimpleTask, ICoroTask
- class TTaskRunnerBase: public TAtomicRefCount<TTaskRunnerBase>, public NActor::TActor<TTaskRunnerBase> {
- friend class NActor::TActor<TTaskRunnerBase>;
- friend class TContinueFunc;
- friend struct TTaskAccessor;
- friend class TSubtaskCompletion;
- private:
- THolder<ITaskBase> Impl;
- ISubtaskListener* const ParentTask;
- // While task is running, it holds extra reference to self.
- //bool HoldsSelfReference;
- bool Done;
- bool SetDoneCalled;
- // Subtasks currently executed.
- TVector<TSubtaskCompletion*> Pending;
- void Act(NActor::TDefaultTag);
- public:
- // Construct task. Task is not automatically started.
- TTaskRunnerBase(IEnv*, ISubtaskListener* parent, TAutoPtr<ITaskBase> impl);
- ~TTaskRunnerBase() override;
- bool IsRunningInThisThread() const;
- void AssertInThisThread() const;
- static TTaskRunnerBase* CurrentTask();
- static ITaskBase* CurrentTaskImpl();
- TString GetStatusSingleLine();
- protected:
- //void RetainRef();
- //void ReleaseRef();
- ITaskBase* GetImplBase() {
- return Impl.Get();
- }
- private:
- // true if need to call again
- virtual bool ReplyReceived() = 0;
- };
- class ITaskBase {
- public:
- virtual ~ITaskBase() {
- }
- };
- // Check that current method executed inside some task.
- bool AreWeInsideTask();
- }
|