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