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