• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_INNER_EVENT_H
17 #define BASE_EVENTHANDLER_INTERFACES_INNER_API_INNER_EVENT_H
18 
19 #include <cstdint>
20 #include <chrono>
21 #include <functional>
22 #include <memory>
23 #include <string>
24 #include <typeinfo>
25 
26 #include "nocopyable.h"
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 class HiTraceId;
31 }
32 
33 namespace AppExecFwk {
34 using HiTraceId = OHOS::HiviewDFX::HiTraceId;
35 
36 class EventHandler;
37 
38 const std::string LINE_SEPARATOR = "\n";
39 
40 class InnerEvent final {
41 public:
42     using Clock = std::chrono::steady_clock;
43     using TimePoint = std::chrono::time_point<Clock>;
44     using Callback = std::function<void()>;
45     using Pointer = std::unique_ptr<InnerEvent, void (*)(InnerEvent *)>;
46 
47     class Waiter {
48     public:
49         Waiter() = default;
50         virtual ~Waiter() = default;
51         DISALLOW_COPY_AND_MOVE(Waiter);
52 
53         virtual void Wait() = 0;
54         virtual void Notify() = 0;
55     };
56 
57     DISALLOW_COPY_AND_MOVE(InnerEvent);
58 
59     /**
60      * Get InnerEvent instance from pool.
61      *
62      * @param innerEventId The id of the event.
63      * @param param Basic parameter of the event, default is 0.
64      * @return Returns the pointer of InnerEvent instance.
65      */
66     static Pointer Get(uint32_t innerEventId, int64_t param = 0);
67 
68     /**
69      * Get InnerEvent instance from pool.
70      *
71      * @param innerEventId The id of the event.
72      * @param object Shared pointer of the object.
73      * @param param Basic parameter of the event, default is 0.
74      * @return Returns the pointer of InnerEvent instance.
75      */
76     template<typename T>
77     static inline Pointer Get(uint32_t innerEventId, const std::shared_ptr<T> &object, int64_t param = 0)
78     {
79         auto event = Get(innerEventId, param);
80         event->SaveSharedPtr(object);
81         return event;
82     }
83 
84     /**
85      * Get InnerEvent instance from pool.
86      *
87      * @param innerEventId The id of the event.
88      * @param object Weak pointer of the object.
89      * @param param Basic parameter of the event, default is 0.
90      * @return Returns the pointer of InnerEvent instance.
91      */
92     template<typename T>
93     static inline Pointer Get(uint32_t innerEventId, const std::weak_ptr<T> &object, int64_t param = 0)
94     {
95         auto event = Get(innerEventId, param);
96         event->SaveSharedPtr(object);
97         return event;
98     }
99 
100     /**
101      * Get InnerEvent instance from pool.
102      *
103      * @param innerEventId The id of the event.
104      * @param object Unique pointer of the object.
105      * @param param Basic parameter of the event, default is 0.
106      * @return Returns the pointer of InnerEvent instance.
107      */
108     template<typename T, typename D>
109     static inline Pointer Get(uint32_t innerEventId, std::unique_ptr<T, D> &&object, int64_t param = 0)
110     {
111         auto event = Get(innerEventId, param);
112         event->SaveUniquePtr(object);
113         return event;
114     }
115 
116     /**
117      * Get InnerEvent instance from pool.
118      *
119      * @param innerEventId The id of the event.
120      * @param object Unique pointer of the object.
121      * @param param Basic parameter of the event, default is 0.
122      * @return Returns the pointer of InnerEvent instance.
123      */
124     template<typename T, typename D>
125     static inline Pointer Get(uint32_t innerEventId, std::unique_ptr<T, D> &object, int64_t param = 0)
126     {
127         auto event = Get(innerEventId, param);
128         event->SaveUniquePtr(object);
129         return event;
130     }
131 
132     /**
133      * Get InnerEvent instance from pool.
134      *
135      * @param innerEventId The id of the event.
136      * @param param Basic parameter of the event.
137      * @param object Shared pointer of the object.
138      * @return Returns the pointer of InnerEvent instance.
139      */
140     template<typename T>
Get(uint32_t innerEventId,int64_t param,const std::shared_ptr<T> & object)141     static inline Pointer Get(uint32_t innerEventId, int64_t param, const std::shared_ptr<T> &object)
142     {
143         auto event = Get(innerEventId, param);
144         event->SaveSharedPtr(object);
145         return event;
146     }
147 
148     /**
149      * Get InnerEvent instance from pool.
150      *
151      * @param innerEventId The id of the event.
152      * @param param Basic parameter of the event.
153      * @param object Weak pointer of the object.
154      * @return Returns the pointer of InnerEvent instance.
155      */
156     template<typename T>
Get(uint32_t innerEventId,int64_t param,const std::weak_ptr<T> & object)157     static inline Pointer Get(uint32_t innerEventId, int64_t param, const std::weak_ptr<T> &object)
158     {
159         auto event = Get(innerEventId, param);
160         event->SaveSharedPtr(object);
161         return event;
162     }
163 
164     /**
165      * Get InnerEvent instance from pool.
166      *
167      * @param innerEventId The id of the event.
168      * @param param Basic parameter of the event.
169      * @param object Unique pointer of the object.
170      * @return Returns the pointer of InnerEvent instance.
171      */
172     template<typename T, typename D>
Get(uint32_t innerEventId,int64_t param,std::unique_ptr<T,D> && object)173     static inline Pointer Get(uint32_t innerEventId, int64_t param, std::unique_ptr<T, D> &&object)
174     {
175         auto event = Get(innerEventId, param);
176         event->SaveUniquePtr(object);
177         return event;
178     }
179 
180     /**
181      * Get InnerEvent instance from pool.
182      *
183      * @param innerEventId The id of the event.
184      * @param param Basic parameter of the event.
185      * @param object Unique pointer of the object.
186      * @return Returns the pointer of InnerEvent instance.
187      */
188     template<typename T, typename D>
Get(uint32_t innerEventId,int64_t param,std::unique_ptr<T,D> & object)189     static inline Pointer Get(uint32_t innerEventId, int64_t param, std::unique_ptr<T, D> &object)
190     {
191         auto event = Get(innerEventId, param);
192         event->SaveUniquePtr(object);
193         return event;
194     }
195 
196     /**
197      * Get InnerEvent instance from pool.
198      *
199      * @param callback Callback for task.
200      * @param name Name of task.
201      * @return Returns the pointer of InnerEvent instance, if callback is invalid, returns nullptr object.
202      */
203     static Pointer Get(const Callback &callback, const std::string &name = std::string());
204 
205     /**
206      * Get InnerEvent instance from pool.
207      *
208      * @return Returns the pointer of InnerEvent instance
209      */
210     static Pointer Get();
211 
212     /**
213      * Get owner of the event.
214      *
215      * @return Returns owner of the event after it has been sent.
216      */
GetOwner()217     inline std::shared_ptr<EventHandler> GetOwner() const
218     {
219         return owner_.lock();
220     }
221 
222     /**
223      * Set owner of the event.
224      *
225      * @param owner Owner for the event.
226      */
SetOwner(const std::shared_ptr<EventHandler> & owner)227     inline void SetOwner(const std::shared_ptr<EventHandler> &owner)
228     {
229         owner_ = owner;
230     }
231 
232     /**
233      * Get handle time of the event.
234      *
235      * @return Returns handle time of the event after it has been sent.
236      */
GetHandleTime()237     inline const TimePoint &GetHandleTime() const
238     {
239         return handleTime_;
240     }
241 
242     /**
243      * Set handle time of the event.
244      *
245      * @param handleTime Handle time of the event.
246      */
SetHandleTime(const TimePoint & handleTime)247     inline void SetHandleTime(const TimePoint &handleTime)
248     {
249         handleTime_ = handleTime;
250     }
251 
252     /**
253      * Get send time of the event.
254      *
255      * @return Returns send time of the event after it has been sent.
256      */
GetSendTime()257     inline const TimePoint &GetSendTime() const
258     {
259         return sendTime_;
260     }
261 
262     /**
263      * Set send time of the event.
264      *
265      * @param sendTime Send time of the event.
266      */
SetSendTime(const TimePoint & sendTime)267     inline void SetSendTime(const TimePoint &sendTime)
268     {
269         sendTime_ = sendTime;
270     }
271 
272     /**
273      * Get id of the event.
274      * Make sure {@link #hasTask} returns false.
275      *
276      * @return Returns id of the event after it has been sent.
277      */
GetInnerEventId()278     inline uint32_t GetInnerEventId() const
279     {
280         return innerEventId_;
281     }
282 
283     /**
284      * Get basic param of the event.
285      * Make sure {@link #hasTask} returns false.
286      *
287      * @return Returns basic param of the event after it has been sent.
288      */
GetParam()289     inline int64_t GetParam() const
290     {
291         return param_;
292     }
293 
294     /**
295      * Get saved object.
296      *
297      * @return Returns shared pointer of saved object.
298      */
299     template<typename T>
GetSharedObject()300     std::shared_ptr<T> GetSharedObject() const
301     {
302         const std::shared_ptr<T> &sharedObject = *reinterpret_cast<const std::shared_ptr<T> *>(smartPtr_);
303         if (CalculateSmartPtrTypeId(sharedObject) == smartPtrTypeId_) {
304             return sharedObject;
305         }
306 
307         const std::weak_ptr<T> &weakObject = *reinterpret_cast<const std::weak_ptr<T> *>(smartPtr_);
308         if (CalculateSmartPtrTypeId(weakObject) == smartPtrTypeId_) {
309             return weakObject.lock();
310         }
311 
312         WarnSmartPtrCastMismatch();
313         return nullptr;
314     }
315 
316     /**
317      * Get saved object.
318      *
319      * @return Returns unique pointer of saved object.
320      */
321     template<typename T>
GetUniqueObject()322     std::unique_ptr<T> GetUniqueObject() const
323     {
324         std::unique_ptr<T> &object = *reinterpret_cast<std::unique_ptr<T> *>(smartPtr_);
325         if (CalculateSmartPtrTypeId(object) == smartPtrTypeId_) {
326             return std::move(object);
327         }
328 
329         WarnSmartPtrCastMismatch();
330         return nullptr;
331     }
332 
333     /**
334      * Get saved object.
335      *
336      * @return Returns unique pointer of saved object.
337      */
338     template<typename T, typename D>
GetUniqueObject()339     std::unique_ptr<T, D> GetUniqueObject() const
340     {
341         std::unique_ptr<T, D> &object = *reinterpret_cast<std::unique_ptr<T, D> *>(smartPtr_);
342         if (CalculateSmartPtrTypeId(object) == smartPtrTypeId_) {
343             return std::move(object);
344         }
345 
346         WarnSmartPtrCastMismatch();
347         return std::unique_ptr<T, D>(nullptr, nullptr);
348     }
349 
350     /**
351      * Get task name.
352      * Make sure {@link #hasTask} returns true.
353      *
354      * @return Returns the task name.
355      */
GetTaskName()356     inline const std::string &GetTaskName() const
357     {
358         return taskName_;
359     }
360 
361     /**
362      * Get task callback.
363      * Make sure {@link #hasTask} returns true.
364      *
365      * @return Returns the callback of the task.
366      */
GetTaskCallback()367     inline const Callback &GetTaskCallback() const
368     {
369         return taskCallback_;
370     }
371 
372     /**
373      * Obtains the Runnable task that will be executed when this InnerEvent is handled.
374      *
375      * @return Returns the callback of the task.
376      */
GetTask()377     inline const Callback &GetTask() const
378     {
379         return GetTaskCallback();
380     }
381 
382     /**
383      * Check whether it takes a task callback in event.
384      *
385      * @return Returns true if it takes a task callback.
386      */
HasTask()387     inline bool HasTask() const
388     {
389         return static_cast<bool>(taskCallback_);
390     }
391 
392     /**
393      * Prints out the internal information about an object in the specified format,
394      * helping you diagnose internal errors of the object.
395      *
396      * @param return The content of the event.
397      */
398     std::string Dump();
399 
400 private:
401     using SmartPtrDestructor = void (*)(void *);
402 
403     InnerEvent() = default;
404     ~InnerEvent() = default;
405 
406     void ClearEvent();
407 
408     static void WarnSmartPtrCastMismatch();
409 
410     template<typename T>
ReleaseSmartPtr(void * smartPtr)411     static void ReleaseSmartPtr(void *smartPtr)
412     {
413         if (smartPtr != nullptr) {
414             delete reinterpret_cast<T *>(smartPtr);
415         }
416     }
417 
418     template<typename T>
SaveSharedPtr(const T & object)419     inline void SaveSharedPtr(const T &object)
420     {
421         smartPtr_ = new T(object);
422         smartPtrDtor_ = ReleaseSmartPtr<T>;
423         smartPtrTypeId_ = CalculateSmartPtrTypeId(object);
424     }
425 
426     template<typename T>
SaveUniquePtr(T & object)427     inline void SaveUniquePtr(T &object)
428     {
429         smartPtr_ = new T(std::move(object));
430         smartPtrDtor_ = ReleaseSmartPtr<T>;
431         smartPtrTypeId_ = CalculateSmartPtrTypeId(object);
432     }
433 
434     /**
435      * if event has trace id ,return trace id, else create span id,
436      * store it in event and return.
437      *
438      * @return return hiTrace Id.
439      */
440     const std::shared_ptr<HiTraceId> GetOrCreateTraceId();
441 
442     /**
443      * return trace id.
444      *
445      * @return return hiTrace Id.
446      */
447     const std::shared_ptr<HiTraceId> GetTraceId();
448 
449     /*
450      * Calculate the type id for different smart pointers.
451      */
452 #ifdef __GXX_RTTI
453     // If RTTI(Run-Time Type Info) is enabled, use hash code of type info.
454     template<typename T>
CalculateSmartPtrTypeId(const T &)455     static inline size_t CalculateSmartPtrTypeId(const T &)
456     {
457         return typeid(T).hash_code();
458     }
459 #else   // #ifdef __GXX_RTTI
460     // Otherwise, generate type id using smart pointer type and the size of the elements they contain.
461     static const size_t SHARED_PTR_TYPE = 0x10000000;
462     static const size_t WEAK_PTR_TYPE = 0x20000000;
463     static const size_t UNIQUE_PTR_TYPE = 0x30000000;
464     static const size_t UNIQUE_PTR_ARRAY_TYPE = 0x40000000;
465 
466     template<typename T>
CalculateSmartPtrTypeId(const std::shared_ptr<T> &)467     static inline size_t CalculateSmartPtrTypeId(const std::shared_ptr<T> &)
468     {
469         return (sizeof(T) | SHARED_PTR_TYPE);
470     }
471 
472     template<typename T>
CalculateSmartPtrTypeId(const std::weak_ptr<T> &)473     static inline size_t CalculateSmartPtrTypeId(const std::weak_ptr<T> &)
474     {
475         return (sizeof(T) | WEAK_PTR_TYPE);
476     }
477 
478     template<typename T, typename D>
CalculateSmartPtrTypeId(const std::unique_ptr<T,D> &)479     static inline size_t CalculateSmartPtrTypeId(const std::unique_ptr<T, D> &)
480     {
481         return (sizeof(T) | (sizeof(D) - 1) | UNIQUE_PTR_TYPE);
482     }
483 
484     template<typename T, typename D>
CalculateSmartPtrTypeId(const std::unique_ptr<T[],D> &)485     static inline size_t CalculateSmartPtrTypeId(const std::unique_ptr<T[], D> &)
486     {
487         return (sizeof(T) | (sizeof(D) - 1) | UNIQUE_PTR_ARRAY_TYPE);
488     }
489 #endif  // #ifdef __GXX_RTTI
490 
491     // Used by event handler to create waiter.
492     const std::shared_ptr<Waiter> &CreateWaiter();
493 
494     // Used by event handler to tell whether event has waiter.
495     bool HasWaiter() const;
496 
497     // Let event pool to create instance of events.
498     friend class InnerEventPool;
499     // Let event handler to access private interface.
500     friend class EventHandler;
501 
502     std::weak_ptr<EventHandler> owner_;
503     TimePoint handleTime_;
504     TimePoint sendTime_;
505 
506     // Event id of the event, if it is not a task object
507     uint32_t innerEventId_{0};
508 
509     // Simple parameter for the event.
510     int64_t param_{0};
511 
512     // Using to save smart pointer
513     size_t smartPtrTypeId_{0};
514     void *smartPtr_{nullptr};
515     SmartPtrDestructor smartPtrDtor_{nullptr};
516 
517     // Task callback and its name.
518     Callback taskCallback_;
519     std::string taskName_;
520 
521     // Used for synchronized event.
522     std::shared_ptr<Waiter> waiter_;
523 
524     // use to store hitrace Id
525     std::shared_ptr<HiTraceId> hiTraceId_;
526 };
527 }  // namespace AppExecFwk
528 }  // namespace OHOS
529 
530 #endif  // #ifndef BASE_EVENTHANDLER_INTERFACES_INNER_API_INNER_EVENT_H
531