• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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