task.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #pragma once
  2. #include "fwd.h"
  3. #include <library/cpp/messagebus/actor/actor.h>
  4. #include <library/cpp/messagebus/misc/atomic_box.h>
  5. #include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
  6. #include <util/generic/noncopyable.h>
  7. #include <util/generic/ptr.h>
  8. #include <util/thread/lfstack.h>
  9. namespace NRainCheck {
  10. struct ISubtaskListener {
  11. virtual void SetDone() = 0;
  12. virtual ~ISubtaskListener() {
  13. }
  14. };
  15. struct TNopSubtaskListener: public ISubtaskListener {
  16. void SetDone() override;
  17. static TNopSubtaskListener Instance;
  18. };
  19. class TSubtaskCompletionFunc {
  20. friend class TSubtaskCompletion;
  21. typedef void (ITaskBase::*TFunc)(TSubtaskCompletion*);
  22. TFunc Func;
  23. public:
  24. TSubtaskCompletionFunc()
  25. : Func(nullptr)
  26. {
  27. }
  28. TSubtaskCompletionFunc(void*)
  29. : Func(nullptr)
  30. {
  31. }
  32. template <typename TTask>
  33. TSubtaskCompletionFunc(void (TTask::*func)(TSubtaskCompletion*))
  34. : Func((TFunc)func)
  35. {
  36. static_assert((std::is_base_of<ITaskBase, TTask>::value), "expect (std::is_base_of<ITaskBase, TTask>::value)");
  37. }
  38. bool operator!() const {
  39. return !Func;
  40. }
  41. };
  42. template <typename T>
  43. class TTaskFuture;
  44. #define SUBTASK_STATE_MAP(XX) \
  45. XX(CREATED, "Initial") \
  46. XX(RUNNING, "Running") \
  47. XX(DONE, "Completed") \
  48. XX(CANCEL_REQUESTED, "Cancel requested, but still executing") \
  49. XX(CANCELED, "Canceled") \
  50. /**/
  51. enum ESubtaskState {
  52. SUBTASK_STATE_MAP(ENUM_VALUE_GEN_NO_VALUE)
  53. };
  54. ENUM_TO_STRING(ESubtaskState, SUBTASK_STATE_MAP)
  55. class TSubtaskCompletion : TNonCopyable, public ISubtaskListener {
  56. friend struct TTaskAccessor;
  57. private:
  58. TAtomicBox<ESubtaskState> State;
  59. TTaskRunnerBase* volatile TaskRunner;
  60. TSubtaskCompletionFunc CompletionFunc;
  61. public:
  62. TSubtaskCompletion()
  63. : State(CREATED)
  64. , TaskRunner()
  65. {
  66. }
  67. ~TSubtaskCompletion() override;
  68. // Either done or cancel requested or cancelled
  69. bool IsComplete() const {
  70. ESubtaskState state = State.Get();
  71. switch (state) {
  72. case RUNNING:
  73. return false;
  74. case DONE:
  75. return true;
  76. case CANCEL_REQUESTED:
  77. return false;
  78. case CANCELED:
  79. return true;
  80. case CREATED:
  81. Y_ABORT("not started");
  82. default:
  83. Y_ABORT("unknown value: %u", (unsigned)state);
  84. }
  85. }
  86. void FireCompletionCallback(ITaskBase*);
  87. void SetCompletionCallback(TSubtaskCompletionFunc func) {
  88. CompletionFunc = func;
  89. }
  90. // Completed, but not cancelled
  91. bool IsDone() const {
  92. return State.Get() == DONE;
  93. }
  94. // Request cancel by actor
  95. // Does nothing but marks task cancelled,
  96. // and allows proceeding to next callback
  97. void Cancel();
  98. // called by service provider implementations
  99. // must not be called by actor
  100. void SetRunning(TTaskRunnerBase* parent);
  101. void SetDone() override;
  102. };
  103. // See ISimpleTask, ICoroTask
  104. class TTaskRunnerBase: public TAtomicRefCount<TTaskRunnerBase>, public NActor::TActor<TTaskRunnerBase> {
  105. friend class NActor::TActor<TTaskRunnerBase>;
  106. friend class TContinueFunc;
  107. friend struct TTaskAccessor;
  108. friend class TSubtaskCompletion;
  109. private:
  110. THolder<ITaskBase> Impl;
  111. ISubtaskListener* const ParentTask;
  112. // While task is running, it holds extra reference to self.
  113. //bool HoldsSelfReference;
  114. bool Done;
  115. bool SetDoneCalled;
  116. // Subtasks currently executed.
  117. TVector<TSubtaskCompletion*> Pending;
  118. void Act(NActor::TDefaultTag);
  119. public:
  120. // Construct task. Task is not automatically started.
  121. TTaskRunnerBase(IEnv*, ISubtaskListener* parent, TAutoPtr<ITaskBase> impl);
  122. ~TTaskRunnerBase() override;
  123. bool IsRunningInThisThread() const;
  124. void AssertInThisThread() const;
  125. static TTaskRunnerBase* CurrentTask();
  126. static ITaskBase* CurrentTaskImpl();
  127. TString GetStatusSingleLine();
  128. protected:
  129. //void RetainRef();
  130. //void ReleaseRef();
  131. ITaskBase* GetImplBase() {
  132. return Impl.Get();
  133. }
  134. private:
  135. // true if need to call again
  136. virtual bool ReplyReceived() = 0;
  137. };
  138. class ITaskBase {
  139. public:
  140. virtual ~ITaskBase() {
  141. }
  142. };
  143. // Check that current method executed inside some task.
  144. bool AreWeInsideTask();
  145. }