Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
control_task.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_ctl/control_task.h
10 //! @brief Control task.
11 
12 #ifndef ROC_CTL_CONTROL_TASK_H_
13 #define ROC_CTL_CONTROL_TASK_H_
14 
15 #include "roc_core/atomic.h"
16 #include "roc_core/list_node.h"
18 #include "roc_core/mutex.h"
19 #include "roc_core/optional.h"
20 #include "roc_core/semaphore.h"
21 #include "roc_core/seqlock.h"
22 #include "roc_core/time.h"
23 
24 namespace roc {
25 namespace ctl {
26 
27 class ControlTaskQueue;
28 class ControlTask;
29 
30 class IControlTaskExecutor;
31 class IControlTaskCompleter;
32 
33 //! Control task execution result.
35  //! Task completed with success.
37 
38  //! Task completed with failure.
40 
41  //! Task wants to be re-executed again as soon as possible.
43 
44  //! Task wants to be paused until is explicitly resumed.
46 };
47 
48 //! Control task implementation function.
49 //! Holds a pointer to method of a class derived from IControlTaskExecutor.
51 
52 //! Base class for control tasks.
54 public:
55  ~ControlTask();
56 
57  //! True if the task succeeded, failed, or cancelled.
58  bool completed() const;
59 
60  //! True if the task succeeded.
61  bool succeeded() const;
62 
63  //! True if the task cancelled.
64  bool cancelled() const;
65 
66 protected:
67  //! Initialize task.
68  //! @tparam E is a class derived from IControlTaskExecutor.
69  //! @p task_func is a method of E which implements the task.
70  template <class E>
72  : state_(StateCompleted)
73  , flags_(0)
74  , renew_guard_(false)
75  , wait_guard_(false)
76  , renewed_deadline_(0)
77  , effective_deadline_(0)
78  , effective_version_(0)
79  , func_(reinterpret_cast<ControlTaskFunc>(task_func))
80  , executor_(NULL)
81  , completer_(NULL)
82  , sem_(NULL) {
83  // ensure that E implements IControlTaskExecutor
84  (void)static_cast<IControlTaskExecutor*>((E*)NULL);
85  }
86 
87 private:
88  friend class ControlTaskQueue;
89 
90  enum State {
91  // task is in ready queue or being fetched from it; after it's
92  // fetched, it will be processed, cancelled, or rescheduled
93  StateReady,
94 
95  // task is in sleeping queue, waiting for its deadline
96  StateSleeping,
97 
98  // task cancellation is initiated
99  StateCancelling,
100 
101  // task is being processed, it's executing or will be executed soon
102  StateProcessing,
103 
104  // task completion is initiated
105  StateCompleting,
106 
107  // task is completed and is not used
108  StateCompleted
109  };
110 
111  enum Flag {
112  // last execution succeeded
113  FlagSucceeded = (1 << 0),
114 
115  // last execution paused
116  FlagPaused = (1 << 2),
117 
118  // task resuming was requested
119  FlagResumed = (1 << 3),
120 
121  // task was cancelled
122  FlagCancelled = (1 << 4),
123 
124  // task destructor was called
125  // seeing this flag indicates use-after-free bug
126  FlagDestroyed = (1 << 5)
127  };
128 
129  // validate task properties
130  static void validate_flags(unsigned task_flags);
131  static void validate_deadline(core::nanoseconds_t deadline,
132  core::seqlock_version_t version);
133 
134  // scheduling state of the task
135  core::Atomic<uint32_t> state_;
136 
137  // additional details about current state
138  core::Atomic<uint32_t> flags_;
139 
140  // guard to cut off concurrent task renewals (only one succeeds)
141  core::Atomic<uint32_t> renew_guard_;
142 
143  // guard to cut off concurrent task waits (only one allowed)
144  core::Atomic<uint32_t> wait_guard_;
145 
146  // new task deadline that is probably not yet taken into account
147  core::Seqlock<core::nanoseconds_t> renewed_deadline_;
148 
149  // currently active task deadline, defines when to execute task:
150  // > 0: absolute time of execution
151  // = 0: execute as soon as possible
152  // < 0: cancel task
153  core::nanoseconds_t effective_deadline_;
154 
155  // version of currently active task deadline
156  core::seqlock_version_t effective_version_;
157 
158  // function to be executed
159  ControlTaskFunc func_;
160 
161  // object that executes task function
162  IControlTaskExecutor* executor_;
163 
164  // object that is notified when the task completes or cancels
165  IControlTaskCompleter* completer_;
166 
167  // semaphore to wait for task completion
168  core::Atomic<core::Semaphore*> sem_;
169  core::Optional<core::Semaphore> sem_holder_;
170 };
171 
172 } // namespace ctl
173 } // namespace roc
174 
175 #endif // ROC_CTL_CONTROL_TASK_H_
Atomic.
Base class for list element.
Definition: list_node.h:26
Base class for control tasks.
Definition: control_task.h:53
bool succeeded() const
True if the task succeeded.
ControlTask(ControlTaskResult(E::*task_func)(ControlTask &))
Initialize task.
Definition: control_task.h:71
bool completed() const
True if the task succeeded, failed, or cancelled.
bool cancelled() const
True if the task cancelled.
Control task executor interface.
Linked list node.
MpscQueue node.
Mutex.
uint32_t seqlock_version_t
Type for holding seqlock value version. Version is changed each value update. May wrap.
Definition: seqlock.h:26
int64_t nanoseconds_t
Nanoseconds.
Definition: time.h:58
ControlTaskResult
Control task execution result.
Definition: control_task.h:34
@ ControlTaskPause
Task wants to be paused until is explicitly resumed.
Definition: control_task.h:45
@ ControlTaskContinue
Task wants to be re-executed again as soon as possible.
Definition: control_task.h:42
@ ControlTaskSuccess
Task completed with success.
Definition: control_task.h:36
@ ControlTaskFailure
Task completed with failure.
Definition: control_task.h:39
ControlTaskResult(IControlTaskExecutor::* ControlTaskFunc)(ControlTask &)
Control task implementation function. Holds a pointer to method of a class derived from IControlTaskE...
Definition: control_task.h:50
Root namespace.
Optionally constructed object.
Seqlock.
Time definitions.