1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_RUNNER_H
17 #define BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_RUNNER_H
18 
19 #include <atomic>
20 
21 #include "event_queue.h"
22 #include "dumper.h"
23 #include "event_inner_logger.h"
24 #include "inner_event.h"
25 
26 namespace OHOS {
27 namespace AppExecFwk {
28 class EventInnerRunner;
29 
30 // Running mode of eventrunner
31 enum class Mode: uint32_t {
32     DEFAULT = 0,  // Default polling mode
33     NO_WAIT,      // One poll mode
34 };
35 
36 enum class ThreadMode: uint32_t {
37     NEW_THREAD = 0,    // for new thread mode, event handler create thread
38     FFRT,           // for new thread mode, use ffrt
39 };
40 
41 class EventRunner final {
42 public:
43     EventRunner() = delete;
44     ~EventRunner();
45     DISALLOW_COPY_AND_MOVE(EventRunner);
46 
47     using DistributeBeginTime = std::function<InnerEvent::TimePoint(const std::string&)>;
48     using DistributeEndTime = std::function<void(const std::string&, const InnerEvent::TimePoint&)>;
49     using CallbackTime = std::function<void(int64_t)>;
50     static DistributeBeginTime distributeBegin_;
51     static DistributeEndTime distributeEnd_;
52     static CallbackTime distributeCallback_;
53 
54     /**
55      * Create new 'EventRunner'.
56      *
57      * @param inNewThread True if create new thread to start the 'EventRunner' automatically.
58      * @param mode default The EventRunner's running mode.
59      * @return Returns shared pointer of the new 'EventRunner'.
60      */
61     static std::shared_ptr<EventRunner> Create(bool inNewThread = true, Mode mode = Mode::DEFAULT);
62 
63     /**
64      * Create new 'EventRunner'.
65      *
66      * @param inNewThread True if create new thread to start the 'EventRunner' automatically.
67      * @param threadMode thread mode, use ffrt or new thread, for inNewThread = true.
68      * @return Returns shared pointer of the new 'EventRunner'.
69      */
70     static std::shared_ptr<EventRunner> Create(bool inNewThread, ThreadMode threadMode);
71 
72     /**
73      * Create new 'EventRunner' and start to run in a new thread.
74      *
75      * @param threadName Thread name of the new created thread.
76      * @param mode default The EventRunner's running mode.
77      * @return Returns shared pointer of the new 'EventRunner'.
78      */
79     static std::shared_ptr<EventRunner> Create(const std::string &threadName, Mode mode = Mode::DEFAULT)
80     {
81         return Create(threadName, mode, ThreadMode::NEW_THREAD);
82     }
83 
84     /**
85      * Create new 'EventRunner' and start to run in a new thread.
86      *
87      * @param threadName Thread name of the new created thread.
88      * @param threadMode thread mode, use ffrt or new thread.
89      * @return Returns shared pointer of the new 'EventRunner'.
90      */
Create(const std::string & threadName,ThreadMode threadMode)91     static std::shared_ptr<EventRunner> Create(const std::string &threadName, ThreadMode threadMode)
92     {
93         return Create(threadName, Mode::DEFAULT, threadMode);
94     }
95 
96     /**
97      * Create new 'EventRunner' and start to run in a new thread.
98      * Eliminate ambiguity, while calling like 'EventRunner::Create("threadName")'.
99      *
100      * @param threadName Thread name of the new created thread.
101      * @param mode default The EventRunner's running mode.
102      * @return Returns shared pointer of the new 'EventRunner'.
103      */
104     static inline std::shared_ptr<EventRunner> Create(const char *threadName, Mode mode = Mode::DEFAULT)
105     {
106         return Create((threadName != nullptr) ? std::string(threadName) : std::string(), mode, ThreadMode::NEW_THREAD);
107     }
108 
109     /**
110      * Create new 'EventRunner' and start to run in a new thread.
111      * Eliminate ambiguity, while calling like 'EventRunner::Create("threadName")'.
112      *
113      * @param threadName Thread name of the new created thread.
114      * @param threadMode thread mode, use ffrt or new thread.
115      * @return Returns shared pointer of the new 'EventRunner'.
116      */
Create(const char * threadName,ThreadMode threadMode)117     static inline std::shared_ptr<EventRunner> Create(const char *threadName, ThreadMode threadMode)
118     {
119         return Create((threadName != nullptr) ? std::string(threadName) : std::string(), Mode::DEFAULT, threadMode);
120     }
121 
122     /**
123      * Get event runner on current thread.
124      *
125      * @return Returns shared pointer of the current 'EventRunner'.
126      */
127     static std::shared_ptr<EventRunner> Current();
128 
129     /**
130      * Start to run the 'EventRunner'. Only used for the 'EventRunner' which is not running in new thread.
131      * Only running on single thread.
132      *
133      * @return Returns 'ERR_OK' on success.
134      */
135     ErrCode Run();
136 
137     /**
138      * Stop to run the 'EventRunner'. Only used for the 'EventRunner' which is not running in new thread.
139      * It is a good practice to call {@link #Stop} on the same thread that called {@link #Run}.
140      *
141      * @return Returns 'ERR_OK' on success.
142      */
143     ErrCode Stop();
144 
145     /**
146      * Get thread name
147      *
148      * @return Returns thread name.
149      */
150     std::string GetRunnerThreadName() const;
151 
152     /**
153      * Get event queue from event runner.
154      * This method only called by 'EventHandler'.
155      *
156      * @return Returns event queue.
157      */
GetEventQueue()158     inline const std::shared_ptr<EventQueue> &GetEventQueue() const
159     {
160         return queue_;
161     }
162 
163     /**
164      * Obtain the event queue of the EventRunner associated with the current thread.
165      *
166      * @return Return current event queue.
167      */
168     static std::shared_ptr<EventQueue> GetCurrentEventQueue();
169 
170     /**
171      * Print out the internal information about an object in the specified format,
172      * helping you diagnose internal errors of the object.
173      *
174      * @param dumpr The Dumper object you have implemented to process the output internal information.
175      */
176     void Dump(Dumper &dumper);
177 
178     /**
179      * Print out the internal information about an object in the specified format,
180      * helping you diagnose internal errors of the object.
181      *
182      * @param runnerInfo runner Info.
183      */
184     void DumpRunnerInfo(std::string& runnerInfo);
185 
186     /**
187      * Set the Logger object for logging messages that are processed by this event runner.
188      *
189      * @param logger The Logger object you have implemented for logging messages.
190      */
191     void SetLogger(const std::shared_ptr<Logger> &logger);
192 
193     /**
194      * Obtain the ID of the worker thread associated with this EventRunner.
195      *
196      * @return thread id.
197      */
198     uint64_t GetThreadId();
199 
200     /**
201      * Obtain the kernel thread ID of the worker thread associated with this EventRunner.
202      *
203      * @return kernel thread id.
204      */
205     uint64_t GetKernelThreadId();
206 
207     /**
208      * Check whether the current thread is the worker thread of this EventRunner.
209      *
210      * @return Returns true if the current thread is the worker thread of this EventRunner; returns false otherwise.
211      */
212     bool IsCurrentRunnerThread();
213 
214     /**
215      * Set the distribution standard expiration time.
216      *
217      * @param deliveryTimeout the distribution standard expiration time.
218      */
SetDeliveryTimeout(int64_t deliveryTimeout)219     void SetDeliveryTimeout(int64_t deliveryTimeout)
220     {
221         deliveryTimeout_ = deliveryTimeout;
222     }
223 
224     /**
225      * Get the distribution standard expiration time.
226      *
227      * @return the distribution standard expiration time.
228      */
GetDeliveryTimeout()229     int64_t GetDeliveryTimeout() const
230     {
231         return deliveryTimeout_;
232     }
233 
234     /**
235      * Set the execution standard timeout period.
236      *
237      * @param distributeTimeout the distribution standard expiration time.
238      */
SetDistributeTimeout(int64_t distributeTimeout)239     void SetDistributeTimeout(int64_t distributeTimeout)
240     {
241         distributeTimeout_ = distributeTimeout;
242     }
243 
244     /**
245      * Get the execution standard timeout period.
246      *
247      * @return the distribution standard expiration time.
248      */
GetDistributeTimeout()249     int64_t GetDistributeTimeout() const
250     {
251         return distributeTimeout_;
252     }
253 
254     /**
255      * Set the main thread timeout period.
256      *
257      * @param distributeTimeout the distribution standard expiration time.
258      */
SetTimeout(int64_t distributeTimeout)259     void SetTimeout(int64_t distributeTimeout)
260     {
261         timeout_ = distributeTimeout;
262     }
263 
264     /**
265      * Set distribute time out callback.
266      *
267      * @param callback Distribute Time out callback.
268      */
SetTimeoutCallback(CallbackTime callback)269     void SetTimeoutCallback(CallbackTime callback)
270     {
271         distributeCallback_ = callback;
272     }
273 
274     /**
275      * Get the execution standard timeout period.
276      *
277      * @return the distribution standard expiration time.
278      */
GetTimeout()279     int64_t GetTimeout() const
280     {
281         return timeout_;
282     }
283 
284     /**
285      * Check if the current application is the main thread.
286      */
287     static bool IsAppMainThread();
288 
289     /**
290      * Set app main thread watcher.
291      *
292      * @param callback Distribute Start Time callback.
293      * @param callback Distribute End Time callback.
294      */
295     void SetMainLooperWatcher(const DistributeBeginTime begin, const DistributeEndTime end);
296 
297     /**
298      * Obtains the EventRunner for the main thread of the application.
299      *
300      * @return Returns the EventRunner for the main thread of the application.
301      */
302     static std::shared_ptr<EventRunner> GetMainEventRunner();
303 
304 private:
305     explicit EventRunner(bool deposit, Mode runningMode = Mode::DEFAULT);
306 
307     friend class EventHandler;
308 
309     static std::shared_ptr<EventRunner> Create(const std::string &threadName, Mode mode, ThreadMode threadMode);
310 
311     /**
312      * Check whether this event runner is running.
313      *
314      * @return if this event runner is running return true otherwise return false
315      */
IsRunning()316     inline bool IsRunning() const
317     {
318         // If this runner is deposited, it it always running
319         return (deposit_ && runningMode_ == Mode::DEFAULT) || (running_.load());
320     }
321 
322     /**
323      * Start event running for no_wait mode in new thread.
324      */
325     void StartRunningForNoWait();
326 
327     int64_t deliveryTimeout_ = 0;
328     int64_t distributeTimeout_ = 0;
329     int64_t timeout_ = 0;
330     bool deposit_{true};
331     std::atomic<bool> running_{false};
332     std::shared_ptr<EventQueue> queue_;
333     std::shared_ptr<EventInnerRunner> innerRunner_;
334     static std::shared_ptr<EventRunner> mainRunner_;
335     std::string currentEventInfo_;
336     Mode runningMode_ = Mode::DEFAULT;
337     ThreadMode threadMode_ = ThreadMode::NEW_THREAD;
338     std::string runnerId_;
339 };
340 }  // namespace AppExecFwk
341 namespace EventHandling = AppExecFwk;
342 }  // namespace OHOS
343 
344 #endif  // #ifndef BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_RUNNER_H
345