1 /* 2 * Copyright (c) 2021-2023 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_QUEUE_BASE_H 17 #define BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_QUEUE_BASE_H 18 19 #include <array> 20 #include <list> 21 #include <map> 22 #include <mutex> 23 24 #include "event_queue.h" 25 26 #define LOCAL_API __attribute__((visibility ("hidden"))) 27 namespace OHOS { 28 namespace AppExecFwk { 29 class IoWaiter; 30 class EventHandler; 31 class DeamonIoWaiter; 32 33 struct CurrentRunningEvent { 34 InnerEvent::TimePoint beginTime_; 35 std::weak_ptr<EventHandler> owner_; 36 uint64_t senderKernelThreadId_{0}; 37 InnerEvent::TimePoint sendTime_; 38 InnerEvent::TimePoint handleTime_; 39 InnerEvent::TimePoint triggerTime_; 40 int64_t param_{0}; 41 bool hasTask_{false}; 42 std::string taskName_; 43 std::string callerInfo_; 44 InnerEvent::EventId innerEventId_ = 0u; 45 CurrentRunningEvent(); 46 CurrentRunningEvent(InnerEvent::TimePoint time, InnerEvent::Pointer &event); 47 }; 48 49 class EventQueueBase : public EventQueue { 50 public: 51 52 EventQueueBase(); 53 explicit EventQueueBase(const std::shared_ptr<IoWaiter> &ioWaiter); 54 ~EventQueueBase(); 55 DISALLOW_COPY_AND_MOVE(EventQueueBase); 56 57 /** 58 * Insert an event into event queue with different priority. 59 * The events will be sorted by handle time. 60 * 61 * @param event Event instance which should be added into event queue. 62 * @param Priority Priority of the event 63 * @param insertType The type of insertint event to queue 64 * 65 * @see #Priority 66 */ 67 bool Insert(InnerEvent::Pointer &event, Priority priority = Priority::LOW, 68 EventInsertType insertType = EventInsertType::AT_END) override; 69 70 /** 71 * Remove events if its owner is invalid. 72 */ 73 void RemoveOrphan() override; 74 75 /** 76 * Remove all events. 77 */ 78 LOCAL_API void RemoveAll() override; 79 80 /** 81 * Remove events with specified requirements. 82 * 83 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 84 */ 85 void Remove(const std::shared_ptr<EventHandler> &owner) override; 86 87 /** 88 * Remove events with specified requirements. 89 * 90 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 91 * @param innerEventId Remove events by event id. 92 */ 93 void Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId) override; 94 95 /** 96 * Remove events with specified requirements. 97 * 98 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 99 * @param innerEventId Remove events by event id. 100 * @param param Remove events by value of param. 101 */ 102 void Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId, int64_t param) override; 103 104 /** 105 * Remove events with specified requirements. 106 * 107 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 108 * @param name Remove events by name of the task. 109 */ 110 bool Remove(const std::shared_ptr<EventHandler> &owner, const std::string &name) override; 111 112 /** 113 * Get event from event queue one by one. 114 * Before calling this method, developers should call {@link #Prepare} first. 115 * If none should be handled right now, the thread will be blocked in this method. 116 * Call {@link #Finish} to exit from blocking. 117 * 118 * @return Returns nullptr if event queue is not prepared yet, or {@link #Finish} is called. 119 * Otherwise returns event instance. 120 */ 121 InnerEvent::Pointer GetEvent() override; 122 123 /** 124 * Get expired event from event queue one by one. 125 * Before calling this method, developers should call {@link #Prepare} first. 126 * 127 * @param nextExpiredTime Output the expired time for the next event. 128 * @return Returns nullptr if none in event queue is expired. 129 * Otherwise returns event instance. 130 */ 131 InnerEvent::Pointer GetExpiredEvent(InnerEvent::TimePoint &nextExpiredTime) override; 132 133 /** 134 * Prints out the internal information about an object in the specified format, 135 * helping you diagnose internal errors of the object. 136 * 137 * @param dumper The Dumper object you have implemented to process the output internal information. 138 */ 139 void Dump(Dumper &dumper) override; 140 141 /** 142 * Print out the internal information about an object in the specified format, 143 * helping you diagnose internal errors of the object. 144 * 145 * @param queueInfo queue Info. 146 */ 147 void DumpQueueInfo(std::string& queueInfo) override; 148 149 /** 150 * Checks whether the current EventHandler is idle. 151 * 152 * @return Returns true if all events have been processed; returns false otherwise. 153 */ 154 bool IsIdle() override; 155 156 /** 157 * Check whether this event queue is empty. 158 * 159 * @return If queue is empty return true otherwise return false. 160 */ 161 bool IsQueueEmpty() override; 162 163 /** 164 * Check whether an event with the given ID can be found among the events that have been sent but not processed. 165 * 166 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 167 * @param innerEventId The id of the event. 168 */ 169 bool HasInnerEvent(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId) override; 170 171 /** 172 * Check whether an event carrying the given param can be found among the events that have been sent but not 173 * processed. 174 * 175 * @param owner The owner of the event which is point to an instance of 'EventHandler'. 176 * @param param The basic parameter of the event. 177 */ 178 bool HasInnerEvent(const std::shared_ptr<EventHandler> &owner, int64_t param) override; 179 180 LOCAL_API void PushHistoryQueueBeforeDistribute(const InnerEvent::Pointer &event) override; 181 182 LOCAL_API void PushHistoryQueueAfterDistribute() override; 183 184 LOCAL_API bool HasPreferEvent(int basePrio) override; 185 186 LOCAL_API std::string DumpCurrentQueueSize() override; 187 188 LOCAL_API PendingTaskInfo QueryPendingTaskInfo(int32_t fileDescriptor) override; 189 /** 190 * execute callback 191 * 192 * @param nextExpiredTime next task execute. 193 */ 194 void TryExecuteObserverCallback(InnerEvent::TimePoint &nextExpiredTime, EventRunnerStage stage); 195 int64_t ExecuteObserverCallback(ObserverTrace obsTrace, EventRunnerStage stage, StageInfo &Info); 196 std::string GetObserverTypeName(Observer observerType); 197 198 /** 199 * clear current observer. 200 */ 201 void ClearObserver(); 202 203 /** 204 * Cancel And Wait. 205 */ 206 LOCAL_API void CancelAndWait() override; 207 208 /** 209 * Add file descriptor listener for a file descriptor. 210 * 211 * @param fileDescriptor File descriptor. 212 * @param events Events from file descriptor, such as input, output, error 213 * @param listener Listener callback. 214 * @return Return 'ERR_OK' on success. 215 */ 216 ErrCode AddFileDescriptorListener(int32_t fileDescriptor, uint32_t events, 217 const std::shared_ptr<FileDescriptorListener> &listener, const std::string &taskName, 218 Priority priority = Priority::HIGH) override; 219 220 /** 221 * Remove all file descriptor listeners for a specified owner. 222 * 223 * @param owner Owner of the event which is point to an instance of 'FileDescriptorListener'. 224 */ 225 void RemoveFileDescriptorListener(const std::shared_ptr<EventHandler> &owner) override; 226 227 /** 228 * Remove file descriptor listener for a file descriptor. 229 * 230 * @param fileDescriptor File descriptor. 231 */ 232 void RemoveFileDescriptorListener(int32_t fileDescriptor) override; 233 234 /** 235 * Prepare event queue, before calling {@link #GetEvent}. 236 * If {@link #Finish} is called, prepare event queue again, before calling {@link #GetEvent}. 237 */ 238 void Prepare() override; 239 240 /** 241 * Exit from blocking in {@link #GetEvent}, and mark the event queue finished. 242 * After calling {@link #Finish}, {@link #GetEvent} never returns any event, until {@link #Prepare} is called. 243 */ 244 void Finish() override; 245 246 void HandleFileDescriptorEvent(int32_t fileDescriptor, uint32_t events, const std::string &name, 247 Priority priority); 248 249 /** 250 * notify observer current vip events is done. 251 * 252 * @param event current event. 253 */ 254 void NotifyObserverVipDone(const InnerEvent::Pointer &event) override; 255 256 /** 257 * base function of notify observer current vip events is done. 258 */ 259 void NotifyObserverVipDoneBase(); 260 261 /** 262 * current queue has vip task 263 */ 264 bool HasVipTask(); 265 266 /** 267 * Obtain the first event of the specified priority queue. 268 * 269 * @param priority Specify priority. 270 * @return Return event handle time of the first event of the specified priority queue if the queue is not null, 271 * or return UINT64_MAX as invalid value. 272 */ 273 inline uint64_t GetQueueFirstEventHandleTime(int32_t priority) override; 274 275 /** 276 * set queue usable status. 277 * 278 * @param usable current usable. 279 */ 280 void SetUsable(bool usable); 281 private: 282 using RemoveFilter = std::function<bool(const InnerEvent::Pointer &)>; 283 using HasFilter = std::function<bool(const InnerEvent::Pointer &)>; 284 285 struct HistoryEvent { 286 uint64_t senderKernelThreadId{0}; 287 std::string taskName; 288 InnerEvent::EventId innerEventId = 0u; 289 bool hasTask{false}; 290 InnerEvent::TimePoint sendTime; 291 InnerEvent::TimePoint handleTime; 292 InnerEvent::TimePoint triggerTime; 293 InnerEvent::TimePoint completeTime; 294 int32_t priority = -1; 295 std::string callerInfo_; 296 }; 297 298 /* 299 * To avoid starvation of lower priority event queue, give a chance to process lower priority events, 300 * after continuous processing several higher priority events. 301 */ 302 static const uint32_t DEFAULT_MAX_HANDLED_EVENT_COUNT = 5; 303 304 // Sub event queues for IMMEDIATE, HIGH and LOW priority. So use value of IDLE as size. 305 static const uint32_t SUB_EVENT_QUEUE_NUM = static_cast<uint32_t>(Priority::IDLE); 306 307 struct SubEventQueue { 308 std::list<InnerEvent::Pointer> queue; 309 uint32_t handledEventsCount{0}; 310 uint32_t maxHandledEventsCount{DEFAULT_MAX_HANDLED_EVENT_COUNT}; 311 uint64_t frontEventHandleTime = UINT64_MAX; 312 }; 313 314 LOCAL_API void Remove(const RemoveFilter &filter); 315 LOCAL_API void RemoveOrphan(const RemoveFilter &filter); 316 LOCAL_API bool HasInnerEvent(const HasFilter &filter); 317 LOCAL_API InnerEvent::Pointer PickFirstVsyncEventLocked(); 318 LOCAL_API InnerEvent::Pointer PickEventLocked(const InnerEvent::TimePoint &now, 319 InnerEvent::TimePoint &nextWakeUpTime); 320 LOCAL_API InnerEvent::Pointer GetExpiredEventLocked(InnerEvent::TimePoint &nextExpiredTime); 321 LOCAL_API std::string HistoryQueueDump(const HistoryEvent &historyEvent); 322 LOCAL_API std::string DumpCurrentRunning(); 323 LOCAL_API void DumpCurrentRunningEventId(const InnerEvent::EventId &innerEventId, std::string &content); 324 LOCAL_API void DumpCurentQueueInfo(Dumper &dumper, uint32_t dumpMaxSize); 325 326 // Sub event queues for different priority. 327 std::array<SubEventQueue, SUB_EVENT_QUEUE_NUM> subEventQueues_; 328 329 // Event queue for IDLE events. 330 std::list<InnerEvent::Pointer> idleEvents_; 331 332 // Next wake up time when block in 'GetEvent'. 333 InnerEvent::TimePoint wakeUpTime_ { InnerEvent::TimePoint::max() }; 334 335 // Mark if in idle mode, and record the start time of idle. 336 InnerEvent::TimePoint idleTimeStamp_ { InnerEvent::Clock::now() }; 337 338 bool isIdle_ {true}; 339 340 // current running event info 341 CurrentRunningEvent currentRunningEvent_; 342 343 static const uint8_t HISTORY_EVENT_NUM_POWER = 32; // 必须是2的幂次,使用位运算取余 344 std::vector<HistoryEvent> historyEvents_; 345 uint8_t historyEventIndex_ = 0; 346 347 bool isExistVipTask_ {false}; 348 }; 349 } // namespace AppExecFwk 350 } // namespace OHOS 351 352 #endif // #ifndef BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_QUEUE_BASE_H 353