Revert "[Tizen] Add TasksCompleted signal at AsyncTaskManager"
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / common / async-task-manager-impl.h
1 #ifndef DALI_INTERNAL_ASYNC_TASK_MANAGER_H
2 #define DALI_INTERNAL_ASYNC_TASK_MANAGER_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
22 #include <dali/devel-api/threading/conditional-wait.h>
23 #include <dali/devel-api/threading/mutex.h>
24 #include <dali/devel-api/threading/thread.h>
25 #include <dali/integration-api/adaptor-framework/log-factory-interface.h>
26 #include <dali/integration-api/adaptor-framework/trace-factory-interface.h>
27 #include <dali/integration-api/processor-interface.h>
28 #include <dali/public-api/common/list-wrapper.h>
29 #include <dali/public-api/object/base-object.h>
30 #include <memory>
31
32 // INTERNAL INCLUDES
33 #include <dali/public-api/adaptor-framework/async-task-manager.h>
34 #include <dali/public-api/adaptor-framework/round-robin-container-view.h>
35
36 namespace Dali
37 {
38 namespace Internal
39 {
40 namespace Adaptor
41 {
42 class AsyncTaskManager;
43
44 /**
45  * The worker thread for async process
46  */
47 class AsyncTaskThread : public Thread
48 {
49 public:
50   /**
51    * Constructor.
52    */
53   AsyncTaskThread(AsyncTaskManager& asyncTaskManager);
54
55   /**
56    * Destructor.
57    */
58   ~AsyncTaskThread() override;
59
60   /**
61    * @brief Request the thread to process the task.
62    * @return True if the request is successed, otherwise false.
63    */
64   bool Request();
65
66 protected:
67   /**
68    * The entry function of the worker thread.
69    */
70   void Run() override;
71
72 private:
73   // Undefined
74   AsyncTaskThread(const AsyncTaskThread& thread) = delete;
75
76   // Undefined
77   AsyncTaskThread& operator=(const AsyncTaskThread& thread) = delete;
78
79 private:
80   ConditionalWait                    mConditionalWait;
81   AsyncTaskManager&                  mAsyncTaskManager;
82   const Dali::LogFactoryInterface&   mLogFactory;   ///< The log factory
83   const Dali::TraceFactoryInterface& mTraceFactory; ///< The trace factory
84   bool                               mDestroyThread;
85   bool                               mIsThreadStarted;
86   bool                               mIsThreadIdle;
87 };
88
89 /**
90  * The manager for async task
91  */
92 class AsyncTaskManager : public Dali::BaseObject, public Integration::Processor
93 {
94 public:
95   /**
96    * Singleton access
97    *
98    * @return The AsyncTaskManager object
99    */
100   static Dali::AsyncTaskManager Get();
101
102   /**
103    * Constructor.
104    */
105   AsyncTaskManager();
106
107   /**
108    * Destructor.
109    */
110   ~AsyncTaskManager() override;
111
112   /**
113    * @copydoc Dali::AsyncTaskManager::AddTask()
114    */
115   void AddTask(AsyncTaskPtr task);
116
117   /**
118    * @copydoc Dali::AsyncTaskManager::RemoveTask()
119    */
120   void RemoveTask(AsyncTaskPtr task);
121
122   /**
123    * Pop the next task out from the completed queue, called by main thread.
124    *
125    * @return The next task in the completed queue.
126    */
127   AsyncTaskPtr PopNextCompletedTask();
128
129   /**
130    * @brief Unregister a previously registered processor
131    */
132   void UnregisterProcessor();
133
134   /**
135    * Execute the callback registered by tasks in the completed queue
136    */
137   void TasksCompleted();
138
139 public: // Worker thread called method
140   /**
141    * Pop the next task out from the queue.
142    *
143    * @return The next task to be processed.
144    */
145   AsyncTaskPtr PopNextTaskToProcess();
146
147   /**
148    * Pop the next task out from the running queue and add this task to the completed queue.
149    * @note After this function, task is invalidate.
150    *
151    * @param[in] task The task added to the queue.
152    */
153   void CompleteTask(AsyncTaskPtr&& task);
154
155 protected: // Implementation of Processor
156   /**
157    * @copydoc Dali::Integration::Processor::Process()
158    */
159   void Process(bool postProcessor) override;
160
161 private:
162   /**
163    * @brief Helper class to keep the relation between AsyncTaskThread and corresponding container
164    */
165   class TaskHelper
166   {
167   public:
168     /**
169      * @brief Create an TaskHelper.
170      *
171      * @param[in] asyncTaskManager Reference to the AsyncTaskManager
172      */
173     TaskHelper(AsyncTaskManager& asyncTaskManager);
174
175     /**
176      * @brief Request the thread to process the task.
177      * @return True if the request succeeds, otherwise false.
178      */
179     bool Request();
180
181   public:
182     TaskHelper(const TaskHelper&) = delete;
183     TaskHelper& operator=(const TaskHelper&) = delete;
184
185     TaskHelper(TaskHelper&& rhs);
186     TaskHelper& operator=(TaskHelper&& rhs) = delete;
187
188   private:
189     /**
190      * @brief Main constructor that used by all other constructors
191      */
192     TaskHelper(std::unique_ptr<AsyncTaskThread> processor, AsyncTaskManager& asyncTaskManager);
193
194   private:
195     std::unique_ptr<AsyncTaskThread> mProcessor;
196     AsyncTaskManager&                mAsyncTaskManager;
197   };
198
199   /**
200    * @brief State of running task
201    */
202   enum class RunningTaskState
203   {
204     RUNNING  = 0, ///< Running task
205     CANCELED = 1, ///< Canceled by user
206   };
207
208   /**
209    * @brief State of complete task
210    */
211   enum class CompletedTaskState
212   {
213     REQUIRE_CALLBACK = 0, ///< Need to execute callback when completed task process.
214     SKIP_CALLBACK    = 1, ///< Do not execute callback
215   };
216
217 private:
218   // Undefined
219   AsyncTaskManager(const AsyncTaskManager& manager);
220
221   // Undefined
222   AsyncTaskManager& operator=(const AsyncTaskManager& manager);
223
224 private:
225   // Keep Task as list since we take tasks by FIFO as default.
226   using AsyncTaskContainer = std::list<AsyncTaskPtr>;
227
228   using AsyncRunningTaskPair      = std::pair<AsyncTaskPtr, RunningTaskState>;
229   using AsyncRunningTaskContainer = std::list<AsyncRunningTaskPair>;
230
231   using AsyncCompletedTaskPair      = std::pair<AsyncTaskPtr, CompletedTaskState>;
232   using AsyncCompletedTaskContainer = std::list<AsyncCompletedTaskPair>;
233
234   AsyncTaskContainer          mWaitingTasks;   ///< The queue of the tasks waiting to async process. Must be locked under mWaitingTasksMutex.
235   AsyncRunningTaskContainer   mRunningTasks;   ///< The queue of the running tasks. Must be locked under mRunningTasksMutex.
236   AsyncCompletedTaskContainer mCompletedTasks; ///< The queue of the tasks with the async process. Must be locked under mCompletedTasksMutex.
237
238   RoundRobinContainerView<TaskHelper> mTasks;
239
240   uint32_t mAvaliableLowPriorityTaskCounts; ///< The number of tasks that can be processed for priority type LOW.
241                                             ///< Be used to select next wating task determining algorithm.
242                                             ///< Note : For thread safety, Please set/get this value under mRunningTasksMutex scope.
243   uint32_t mWaitingHighProirityTaskCounts;  ///< The number of tasks that waiting now for priority type HIGH.
244                                             ///< Be used to select next wating task determining algorithm.
245                                             ///< Note : For thread safety, Please set/get this value under mWaitingTasksMutex scope.
246
247   Dali::Mutex mWaitingTasksMutex;   ///< Mutex for mWaitingTasks. We can lock mRunningTasksMutex and mCompletedTasksMutex under this scope.
248   Dali::Mutex mRunningTasksMutex;   ///< Mutex for mRunningTasks. We can lock mCompletedTasksMutex under this scope.
249   Dali::Mutex mCompletedTasksMutex; ///< Mutex for mCompletedTasks. We cannot lock any mutex under this scope.
250
251   struct CacheImpl;
252   std::unique_ptr<CacheImpl> mCacheImpl; ///< Cache interface for AsyncTaskManager.
253
254   std::unique_ptr<EventThreadCallback> mTrigger;
255
256   bool mProcessorRegistered : 1;
257 };
258
259 } // namespace Adaptor
260
261 } // namespace Internal
262
263 inline Internal::Adaptor::AsyncTaskManager& GetImplementation(Dali::AsyncTaskManager& obj)
264 {
265   DALI_ASSERT_ALWAYS(obj && "AsyncTaskManager is empty");
266
267   Dali::BaseObject& handle = obj.GetBaseObject();
268
269   return static_cast<Internal::Adaptor::AsyncTaskManager&>(handle);
270 }
271
272 inline const Internal::Adaptor::AsyncTaskManager& GetImplementation(const Dali::AsyncTaskManager& obj)
273 {
274   DALI_ASSERT_ALWAYS(obj && "AsyncTaskManager is empty");
275
276   const Dali::BaseObject& handle = obj.GetBaseObject();
277
278   return static_cast<const Internal::Adaptor::AsyncTaskManager&>(handle);
279 }
280
281 } // namespace Dali
282
283 #endif