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_H 17 #define BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_QUEUE_H 18 19 #include <array> 20 #include <functional> 21 #include <list> 22 #include <map> 23 #include <mutex> 24 25 #include "inner_event.h" 26 #include "event_handler_errors.h" 27 #include "file_descriptor_listener.h" 28 #include "dumper.h" 29 30 namespace OHOS { 31 namespace AppExecFwk { 32 class IoWaiter; 33 class EventHandler; 34 class DeamonIoWaiter; 35 struct PendingTaskInfo; 36 37 enum class EventInsertType: uint32_t { 38 // Insert event at end 39 AT_END = 0, 40 // Insert event at front 41 AT_FRONT 42 }; 43 44 enum class Observer { 45 ARKTS_GC, 46 }; 47 48 enum class EventRunnerStage { 49 // enter loop 50 STAGE_ENTRY_RUNNER = 1<<0, 51 // exit loop 52 STAGE_EXIT_RUNNER = 1<<1, 53 // waiting 54 STAGE_BEFORE_WAITING = 1<<2, 55 // recover form sleeping 56 STAGE_AFTER_WAITING = 1<<3, 57 // invaild key 58 STAGE_INVAILD = 0, 59 }; 60 61 struct StageInfo { 62 // STAGE_BEFORE_WAITING, timesteap 63 int64_t timestamp; 64 // STAGE_BEFORE_WAITING, milliseconds 65 int32_t sleepTime; 66 // STAGE_AFTER_WAITING 67 int reason; 68 }; 69 70 using EventRunnerObserverCallBack = std::function<int(EventRunnerStage stage, const StageInfo* info)>; 71 72 struct EventRunnerObserver { 73 Observer observer; 74 uint32_t stages; 75 EventRunnerObserverCallBack notifyCb; ClearObserverEventRunnerObserver76 void ClearObserver() 77 { 78 stages = static_cast<uint32_t>(EventRunnerStage::STAGE_INVAILD); 79 notifyCb = nullptr; 80 } 81 }; 82 83 struct ObserverTrace { 84 std::string source; 85 std::string stage; ObserverTraceObserverTrace86 ObserverTrace() {}; ObserverTraceObserverTrace87 ObserverTrace(std::string currentSource, std::string currentStage) 88 : source(currentSource), stage(currentStage) {} getTraceInfoObserverTrace89 std::string getTraceInfo() 90 { 91 std::string traceInfo; 92 traceInfo.append("Et-obs:"); 93 if (stage.empty()) { 94 traceInfo.append(" "); 95 } else { 96 traceInfo.append(stage); 97 } 98 traceInfo.append(","); 99 if (!source.empty()) { 100 traceInfo.append(source); 101 } 102 return traceInfo; 103 } 104 }; 105 106 class EventQueue { 107 public: 108 // Priority for the events 109 enum class Priority : uint32_t { 110 // The highest priority queue, should be distributed until the tasks in the queue are completed. 111 VIP = 0, 112 // Event that should be distributed at once if possible. 113 IMMEDIATE, 114 // High priority event, sorted by handle time, should be distributed before low priority event. 115 HIGH, 116 // Normal event, sorted by handle time. 117 LOW, 118 // Event that should be distributed only if no other event right now. 119 IDLE, 120 }; 121 122 EventQueue(); 123 explicit EventQueue(const std::shared_ptr<IoWaiter> &ioWaiter); 124 virtual ~EventQueue(); 125 DISALLOW_COPY_AND_MOVE(EventQueue); 126 127 /** 128 * Insert an event into event queue with different priority. 129 * The events will be sorted by handle time. 130 * 131 * @param event Event instance which should be added into event queue. 132 * @param Priority Priority of the event 133 * @param insertType The type of insertint event to queue 134 * 135 * @see #Priority 136 */ 137 virtual void Insert(InnerEvent::Pointer &event, Priority priority = Priority::LOW, 138 EventInsertType insertType = EventInsertType::AT_END) = 0; 139 140 /** 141 * Remove events if its owner is invalid, for base queue. 142 */ RemoveOrphan()143 virtual void RemoveOrphan() {}; 144 145 /** 146 * Remove events if its owner is invalid, for ffrt queue. 147 */ RemoveOrphanByHandlerId(const std::string & handlerId)148 virtual void RemoveOrphanByHandlerId(const std::string& handlerId) { (void)handlerId; }; 149 150 /** 151 * Remove all events. 152 */ 153 virtual void RemoveAll() = 0; 154 155 /** 156 * Remove events with specified requirements. 157 * 158 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 159 */ 160 virtual void Remove(const std::shared_ptr<EventHandler> &owner) = 0; 161 162 /** 163 * Remove events with specified requirements. 164 * 165 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 166 * @param innerEventId Remove events by event id. 167 */ 168 virtual void Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId) = 0; 169 170 /** 171 * Remove events with specified requirements. 172 * 173 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 174 * @param innerEventId Remove events by event id. 175 * @param param Remove events by value of param. 176 */ 177 virtual void Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId, int64_t param) = 0; 178 179 /** 180 * Remove events with specified requirements. 181 * 182 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 183 * @param name Remove events by name of the task. 184 */ 185 virtual bool Remove(const std::shared_ptr<EventHandler> &owner, const std::string &name) = 0; 186 187 /** 188 * Add file descriptor listener for a file descriptor. 189 * 190 * @param fileDescriptor File descriptor. 191 * @param events Events from file descriptor, such as input, output, error 192 * @param listener Listener callback. 193 * @return Return 'ERR_OK' on success. 194 */ 195 ErrCode AddFileDescriptorListener(int32_t fileDescriptor, uint32_t events, 196 const std::shared_ptr<FileDescriptorListener> &listener, const std::string &taskName, 197 Priority priority = Priority::HIGH); 198 199 /** 200 * Remove all file descriptor listeners for a specified owner. 201 * 202 * @param owner Owner of the event which is point to an instance of 'FileDescriptorListener'. 203 */ 204 void RemoveFileDescriptorListener(const std::shared_ptr<EventHandler> &owner); 205 206 /** 207 * Remove file descriptor listener for a file descriptor. 208 * 209 * @param fileDescriptor File descriptor. 210 */ 211 void RemoveFileDescriptorListener(int32_t fileDescriptor); 212 213 /** 214 * Prepare event queue, before calling {@link #GetEvent}. 215 * If {@link #Finish} is called, prepare event queue again, before calling {@link #GetEvent}. 216 */ 217 void Prepare(); 218 219 /** 220 * Exit from blocking in {@link #GetEvent}, and mark the event queue finished. 221 * After calling {@link #Finish}, {@link #GetEvent} never returns any event, until {@link #Prepare} is called. 222 */ 223 void Finish(); 224 225 /** 226 * Get event from event queue one by one. 227 * Before calling this method, developers should call {@link #Prepare} first. 228 * If none should be handled right now, the thread will be blocked in this method. 229 * Call {@link #Finish} to exit from blocking. 230 * 231 * @return Returns nullptr if event queue is not prepared yet, or {@link #Finish} is called. 232 * Otherwise returns event instance. 233 */ 234 virtual InnerEvent::Pointer GetEvent(); 235 236 /** 237 * Get expired event from event queue one by one. 238 * Before calling this method, developers should call {@link #Prepare} first. 239 * 240 * @param nextExpiredTime Output the expired time for the next event. 241 * @return Returns nullptr if none in event queue is expired. 242 * Otherwise returns event instance. 243 */ 244 virtual InnerEvent::Pointer GetExpiredEvent(InnerEvent::TimePoint &nextExpiredTime); 245 246 /** 247 * Prints out the internal information about an object in the specified format, 248 * helping you diagnose internal errors of the object. 249 * 250 * @param dumper The Dumper object you have implemented to process the output internal information. 251 */ 252 virtual void Dump(Dumper &dumper) = 0; 253 254 /** 255 * Print out the internal information about an object in the specified format, 256 * helping you diagnose internal errors of the object. 257 * 258 * @param queueInfo queue Info. 259 */ 260 virtual void DumpQueueInfo(std::string& queueInfo) = 0; 261 262 /** 263 * Checks whether the current EventHandler is idle. 264 * 265 * @return Returns true if all events have been processed; returns false otherwise. 266 */ 267 virtual bool IsIdle() = 0; 268 269 /** 270 * Check whether this event queue is empty. 271 * 272 * @return If queue is empty return true otherwise return false. 273 */ 274 virtual bool IsQueueEmpty() = 0; 275 276 /** 277 * Check whether an event with the given ID can be found among the events that have been sent but not processed. 278 * 279 * @param owner Owner of the event which is point to an instance of 'EventHandler'. 280 * @param innerEventId The id of the event. 281 */ 282 virtual bool HasInnerEvent(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId) = 0; 283 284 /** 285 * Check whether an event carrying the given param can be found among the events that have been sent but not 286 * processed. 287 * 288 * @param owner The owner of the event which is point to an instance of 'EventHandler'. 289 * @param param The basic parameter of the event. 290 */ 291 virtual bool HasInnerEvent(const std::shared_ptr<EventHandler> &owner, int64_t param) = 0; 292 PushHistoryQueueBeforeDistribute(const InnerEvent::Pointer & event)293 virtual void PushHistoryQueueBeforeDistribute(const InnerEvent::Pointer &event) { (void)event; } 294 PushHistoryQueueAfterDistribute()295 virtual void PushHistoryQueueAfterDistribute() {} 296 297 virtual bool HasPreferEvent(int basePrio) = 0; 298 299 virtual std::string DumpCurrentQueueSize() = 0; 300 301 /** 302 * Check whether there are currenty file descriptors is need to be processed. 303 */ 304 void CheckFileDescriptorEvent(); 305 306 /** 307 * Set waiter mode, true for deamon io waiter 308 */ SetIoWaiter(bool useDeamonIoWaiter)309 void SetIoWaiter(bool useDeamonIoWaiter) 310 { 311 useDeamonIoWaiter_ = useDeamonIoWaiter; 312 } 313 314 /** 315 * Get ffrt queue handler type, only for ffrt thread mode. 316 */ GetFfrtQueue()317 virtual void* GetFfrtQueue() { return nullptr; } 318 319 /** 320 * Insert task to ffrt queue, and wait to handled, only for ffrt thread mode. 321 */ 322 virtual void InsertSyncEvent(InnerEvent::Pointer &event, Priority priority = Priority::LOW, 323 EventInsertType insertType = EventInsertType::AT_END) 324 { 325 (void)event; 326 (void)priority; 327 (void)insertType; 328 } 329 330 /** 331 * Get pending task info 332 */ 333 virtual PendingTaskInfo QueryPendingTaskInfo(int32_t fileDescriptor) = 0; 334 /** 335 * add observer 336 * 337 * @param observer runner observer. 338 * @param stages The stages of observer 339 * @param callback observer callback. 340 */ AddObserver(Observer observer,uint32_t stages,EventRunnerObserverCallBack callback)341 void AddObserver(Observer observer, uint32_t stages, EventRunnerObserverCallBack callback) 342 { 343 observer_.observer = observer; 344 observer_.notifyCb = callback; 345 observer_.stages = stages; 346 } 347 348 /** 349 * Cancel And Wait 350 */ 351 virtual void CancelAndWait() = 0; 352 353 private: 354 355 void HandleFileDescriptorEvent(int32_t fileDescriptor, uint32_t events, const std::string &name, 356 Priority priority); 357 bool EnsureIoWaiterSupportListerningFileDescriptorLocked(); 358 bool AddFileDescriptorByFd(int32_t fileDescriptor, uint32_t events, const std::string &taskName, 359 const std::shared_ptr<FileDescriptorListener>& listener, EventQueue::Priority priority); 360 protected: 361 void RemoveInvalidFileDescriptor(); 362 void WaitUntilLocked(const InnerEvent::TimePoint &when, std::unique_lock<std::mutex> &lock); 363 364 std::mutex queueLock_; 365 366 std::atomic_bool usable_ {true}; 367 368 bool isIdle_ {true}; 369 370 // Mark if the event queue is finished. 371 bool finished_ {true}; 372 373 // IO waiter used to block if no events while calling 'GetEvent'. 374 std::shared_ptr<IoWaiter> ioWaiter_; 375 376 // select different epoll 377 bool useDeamonIoWaiter_ = false; 378 379 // File descriptor listeners to handle IO events. 380 std::map<int32_t, std::shared_ptr<FileDescriptorListener>> listeners_; 381 382 EventRunnerObserver observer_ = {.stages = static_cast<uint32_t>(EventRunnerStage::STAGE_INVAILD), 383 .notifyCb = nullptr}; 384 }; 385 } // namespace AppExecFwk 386 } // namespace OHOS 387 388 #endif // #ifndef BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_QUEUE_H 389