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