2b317896a0baab0044264e8a6bebb4b6d15f9ce5
[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/processor-interface.h>
27 #include <dali/public-api/object/base-object.h>
28 #include <memory>
29
30 // INTERNAL INCLUDES
31 #include <dali/public-api/adaptor-framework/async-task-manager.h>
32 #include <dali/public-api/adaptor-framework/round-robin-container-view.h>
33
34 namespace Dali
35 {
36 namespace Internal
37 {
38 namespace Adaptor
39 {
40 class AsyncTaskManager;
41
42 /**
43  * The worker thread for async process
44  */
45 class AsyncTaskThread : public Thread
46 {
47 public:
48   /**
49    * Constructor.
50    */
51   AsyncTaskThread(AsyncTaskManager& asyncTaskManager);
52
53   /**
54    * Destructor.
55    */
56   ~AsyncTaskThread() override;
57
58   /**
59    * @brief Request the thread to process the task.
60    * @return True if the request is successed, otherwise false.
61    */
62   bool Request();
63
64 protected:
65   /**
66    * The entry function of the worker thread.
67    */
68   void Run() override;
69
70 private:
71   // Undefined
72   AsyncTaskThread(const AsyncTaskThread& thread) = delete;
73
74   // Undefined
75   AsyncTaskThread& operator=(const AsyncTaskThread& thread) = delete;
76
77 private:
78   ConditionalWait                  mConditionalWait;
79   AsyncTaskManager&                mAsyncTaskManager;
80   const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
81   bool                             mDestroyThread;
82   bool                             mIsThreadStarted;
83   bool                             mIsThreadIdle;
84 };
85
86 /**
87  * The manager for async task
88  */
89 class AsyncTaskManager : public Dali::BaseObject, public Integration::Processor
90 {
91 public:
92   /**
93    * Singleton access
94    *
95    * @return The AsyncTaskManager object
96    */
97   static Dali::AsyncTaskManager Get();
98
99   /**
100    * Constructor.
101    */
102   AsyncTaskManager();
103
104   /**
105    * Destructor.
106    */
107   ~AsyncTaskManager() override;
108
109   /**
110    * @copydoc Dali::AsyncTaskManager::AddTask()
111    */
112   void AddTask(AsyncTaskPtr task);
113
114   /**
115    * @copydoc Dali::AsyncTaskManager::RemoveTask()
116    */
117   void RemoveTask(AsyncTaskPtr task);
118
119   /**
120    * Pop the next task out from the queue.
121    *
122    * @return The next task to be processed.
123    */
124   AsyncTaskPtr PopNextTaskToProcess();
125
126   /**
127    * Pop the next task out from the completed queue, called by main thread.
128    *
129    * @return The next task in the completed queue.
130    */
131   AsyncTaskPtr PopNextCompletedTask();
132
133   /**
134    * Pop the next task out from the running queue and add this task to the completed queue.
135    *
136    * @param[in] task The task added to the queue.
137    */
138   void CompleteTask(AsyncTaskPtr task);
139
140   /**
141    * @brief Unregister a previously registered processor
142    */
143   void UnregisterProcessor();
144
145   /**
146    * Execute the callback registered by tasks in the completed queue
147    */
148   void TasksCompleted();
149
150   /**
151    * @copydoc Dali::Integration::Processor::Process()
152    */
153   void Process(bool postProcessor) override;
154
155 private:
156   /**
157    * @brief Helper class to keep the relation between AsyncTaskThread and corresponding container
158    */
159   class TaskHelper
160   {
161   public:
162     /**
163      * @brief Create an TaskHelper.
164      *
165      * @param[in] asyncTaskManager Reference to the AsyncTaskManager
166      */
167     TaskHelper(AsyncTaskManager& asyncTaskManager);
168
169     /**
170      * @brief Request the thread to process the task.
171      * @return True if the request succeeds, otherwise false.
172      */
173     bool Request();
174
175   public:
176     TaskHelper(const TaskHelper&) = delete;
177     TaskHelper& operator=(const TaskHelper&) = delete;
178
179     TaskHelper(TaskHelper&& rhs);
180     TaskHelper& operator=(TaskHelper&& rhs) = delete;
181
182   private:
183     /**
184      * @brief Main constructor that used by all other constructors
185      */
186     TaskHelper(std::unique_ptr<AsyncTaskThread> processor, AsyncTaskManager& asyncTaskManager);
187
188   private:
189     std::unique_ptr<AsyncTaskThread> mProcessor;
190     AsyncTaskManager&                mAsyncTaskManager;
191   };
192
193 private:
194   // Undefined
195   AsyncTaskManager(const AsyncTaskManager& manager);
196
197   // Undefined
198   AsyncTaskManager& operator=(const AsyncTaskManager& manager);
199
200 private:
201   std::vector<AsyncTaskPtr> mWaitingTasks;   //The queue of the tasks waiting to async process
202   std::vector<AsyncTaskPtr> mCompletedTasks; //The queue of the tasks with the async process
203
204   using AsyncTaskPair = std::pair<AsyncTaskPtr, bool>;
205   std::vector<AsyncTaskPair> mRunningTasks; ///< The queue of the running tasks
206
207   RoundRobinContainerView<TaskHelper> mTasks;
208
209   uint32_t mAvaliableLowPriorityTaskCounts; ///< The number of tasks that can be processed for proirity type LOW.
210                                             ///< Be used to select next wating task determining algorithm.
211
212   Dali::Mutex                          mMutex;
213   std::unique_ptr<EventThreadCallback> mTrigger;
214   bool                                 mProcessorRegistered;
215 };
216
217 } // namespace Adaptor
218
219 } // namespace Internal
220
221 inline Internal::Adaptor::AsyncTaskManager& GetImplementation(Dali::AsyncTaskManager& obj)
222 {
223   DALI_ASSERT_ALWAYS(obj && "AsyncTaskManager is empty");
224
225   Dali::BaseObject& handle = obj.GetBaseObject();
226
227   return static_cast<Internal::Adaptor::AsyncTaskManager&>(handle);
228 }
229
230 inline const Internal::Adaptor::AsyncTaskManager& GetImplementation(const Dali::AsyncTaskManager& obj)
231 {
232   DALI_ASSERT_ALWAYS(obj && "AsyncTaskManager is empty");
233
234   const Dali::BaseObject& handle = obj.GetBaseObject();
235
236   return static_cast<const Internal::Adaptor::AsyncTaskManager&>(handle);
237 }
238
239 } // namespace Dali
240
241 #endif