• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_EVENT_QUEUE_H
17 #define BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_QUEUE_H
18 
19 #include <array>
20 #include <list>
21 #include <map>
22 #include <mutex>
23 
24 #include "inner_event.h"
25 #include "event_handler_errors.h"
26 #include "file_descriptor_listener.h"
27 #include "dumper.h"
28 #include "logger.h"
29 
30 namespace OHOS {
31 namespace AppExecFwk {
32 class IoWaiter;
33 class EventHandler;
34 
35 struct CurrentRunningEvent {
36     InnerEvent::TimePoint beginTime_;
37     std::weak_ptr<EventHandler> owner_;
38     uint64_t senderKernelThreadId_{0};
39     InnerEvent::TimePoint sendTime_;
40     InnerEvent::TimePoint handleTime_;
41     int64_t param_{0};
42     bool hasTask_{false};
43     std::string taskName_;
44     uint32_t innerEventId_{0};
45     CurrentRunningEvent();
46     CurrentRunningEvent(InnerEvent::TimePoint time, InnerEvent::Pointer &event);
47 };
48 
49 class EventQueue final {
50 public:
51     // Priority for the events
52     enum class Priority : uint32_t {
53         // Event that should be distributed at once if possible.
54         IMMEDIATE = 0,
55         // High priority event, sorted by handle time, should be distributed before low priority event.
56         HIGH,
57         // Normal event, sorted by handle time.
58         LOW,
59         // Event that should be distributed only if no other event right now.
60         IDLE,
61     };
62 
63     EventQueue();
64     explicit EventQueue(const std::shared_ptr<IoWaiter> &ioWaiter);
65     ~EventQueue();
66     DISALLOW_COPY_AND_MOVE(EventQueue);
67 
68     /**
69      * Insert an event into event queue with different priority.
70      * The events will be sorted by handle time.
71      *
72      * @param event Event instance which should be added into event queue.
73      * @param Priority Priority of the event
74      *
75      * @see #Priority
76      */
77     void Insert(InnerEvent::Pointer &event, Priority priority = Priority::LOW);
78 
79     /**
80      * Remove events if its owner is invalid.
81      */
82     void RemoveOrphan();
83 
84     /**
85      * Remove all events.
86      */
87     void RemoveAll();
88 
89     /**
90      * Remove events with specified requirements.
91      *
92      * @param owner Owner of the event which is point to an instance of 'EventHandler'.
93      */
94     void Remove(const std::shared_ptr<EventHandler> &owner);
95 
96     /**
97      * Remove events with specified requirements.
98      *
99      * @param owner Owner of the event which is point to an instance of 'EventHandler'.
100      * @param innerEventId Remove events by event id.
101      */
102     void Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId);
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 innerEventId Remove events by event id.
109      * @param param Remove events by value of param.
110      */
111     void Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId, int64_t param);
112 
113     /**
114      * Remove events with specified requirements.
115      *
116      * @param owner Owner of the event which is point to an instance of 'EventHandler'.
117      * @param name Remove events by name of the task.
118      */
119     void Remove(const std::shared_ptr<EventHandler> &owner, const std::string &name);
120 
121     /**
122      * Add file descriptor listener for a file descriptor.
123      *
124      * @param fileDescriptor File descriptor.
125      * @param events Events from file descriptor, such as input, output, error
126      * @param listener Listener callback.
127      * @return Return 'ERR_OK' on success.
128      */
129     ErrCode AddFileDescriptorListener(
130         int32_t fileDescriptor, uint32_t events, const std::shared_ptr<FileDescriptorListener> &listener);
131 
132     /**
133      * Remove all file descriptor listeners for a specified owner.
134      *
135      * @param owner Owner of the event which is point to an instance of 'FileDescriptorListener'.
136      */
137     void RemoveFileDescriptorListener(const std::shared_ptr<EventHandler> &owner);
138 
139     /**
140      * Remove file descriptor listener for a file descriptor.
141      *
142      * @param fileDescriptor File descriptor.
143      */
144     void RemoveFileDescriptorListener(int32_t fileDescriptor);
145 
146     /**
147      * Prepare event queue, before calling {@link #GetEvent}.
148      * If {@link #Finish} is called, prepare event queue again, before calling {@link #GetEvent}.
149      */
150     void Prepare();
151 
152     /**
153      * Exit from blocking in {@link #GetEvent}, and mark the event queue finished.
154      * After calling {@link #Finish}, {@link #GetEvent} never returns any event, until {@link #Prepare} is called.
155      */
156     void Finish();
157 
158     /**
159      * Get event from event queue one by one.
160      * Before calling this method, developers should call {@link #Prepare} first.
161      * If none should be handled right now, the thread will be blocked in this method.
162      * Call {@link #Finish} to exit from blocking.
163      *
164      * @return Returns nullptr if event queue is not prepared yet, or {@link #Finish} is called.
165      * Otherwise returns event instance.
166      */
167     InnerEvent::Pointer GetEvent();
168 
169     /**
170      * Get expired event from event queue one by one.
171      * Before calling this method, developers should call {@link #Prepare} first.
172      *
173      * @param nextExpiredTime Output the expired time for the next event.
174      * @return Returns nullptr if none in event queue is expired.
175      * Otherwise returns event instance.
176      */
177     InnerEvent::Pointer GetExpiredEvent(InnerEvent::TimePoint &nextExpiredTime);
178 
179     /**
180      * Prints out the internal information about an object in the specified format,
181      * helping you diagnose internal errors of the object.
182      *
183      * @param dumper The Dumper object you have implemented to process the output internal information.
184      */
185     void Dump(Dumper &dumper);
186 
187     /**
188      * Print out the internal information about an object in the specified format,
189      * helping you diagnose internal errors of the object.
190      *
191      * @param queueInfo queue Info.
192      */
193     void DumpQueueInfo(std::string& queueInfo);
194 
195     /**
196      * Checks whether the current EventHandler is idle.
197      *
198      * @return Returns true if all events have been processed; returns false otherwise.
199      */
200     bool IsIdle();
201 
202     /**
203      * Check whether this event queue is empty.
204      *
205      * @return If queue is empty return true otherwise return false.
206      */
207     bool IsQueueEmpty();
208 
209     /**
210      * Check whether an event with the given ID can be found among the events that have been sent but not processed.
211      *
212      * @param owner Owner of the event which is point to an instance of 'EventHandler'.
213      * @param innerEventId The id of the event.
214      */
215     bool HasInnerEvent(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId);
216 
217     /**
218      * Check whether an event carrying the given param can be found among the events that have been sent but not
219      * processed.
220      *
221      * @param owner The owner of the event which is point to an instance of 'EventHandler'.
222      * @param param The basic parameter of the event.
223      */
224     bool HasInnerEvent(const std::shared_ptr<EventHandler> &owner, int64_t param);
225 
226 private:
227     using RemoveFilter = std::function<bool(const InnerEvent::Pointer &)>;
228     using HasFilter = std::function<bool(const InnerEvent::Pointer &)>;
229 
230     /*
231      * To avoid starvation of lower priority event queue, give a chance to process lower priority events,
232      * after continuous processing several higher priority events.
233      */
234     static const uint32_t DEFAULT_MAX_HANDLED_EVENT_COUNT = 5;
235 
236     // Sub event queues for IMMEDIATE, HIGH and LOW priority. So use value of IDLE as size.
237     static const uint32_t SUB_EVENT_QUEUE_NUM = static_cast<uint32_t>(Priority::IDLE);
238 
239     struct SubEventQueue {
240         std::list<InnerEvent::Pointer> queue;
241         uint32_t handledEventsCount{0};
242         uint32_t maxHandledEventsCount{DEFAULT_MAX_HANDLED_EVENT_COUNT};
243     };
244 
245     void Remove(const RemoveFilter &filter);
246     bool HasInnerEvent(const HasFilter &filter);
247     InnerEvent::Pointer PickEventLocked(const InnerEvent::TimePoint &now, InnerEvent::TimePoint &nextWakeUpTime);
248     InnerEvent::Pointer GetExpiredEventLocked(InnerEvent::TimePoint &nextExpiredTime);
249     void WaitUntilLocked(const InnerEvent::TimePoint &when, std::unique_lock<std::mutex> &lock);
250     void HandleFileDescriptorEvent(int32_t fileDescriptor, uint32_t events);
251     bool EnsureIoWaiterSupportListerningFileDescriptorLocked();
252     std::string DumpCurrentRunning();
253     std::mutex queueLock_;
254 
255     std::atomic_bool usable_ {true};
256 
257     // Sub event queues for different priority.
258     std::array<SubEventQueue, SUB_EVENT_QUEUE_NUM> subEventQueues_;
259 
260     // Event queue for IDLE events.
261     std::list<InnerEvent::Pointer> idleEvents_;
262 
263     // Next wake up time when block in 'GetEvent'.
264     InnerEvent::TimePoint wakeUpTime_ { InnerEvent::TimePoint::max() };
265 
266     // Mark if in idle mode, and record the start time of idle.
267     InnerEvent::TimePoint idleTimeStamp_ { InnerEvent::Clock::now() };
268 
269     bool isIdle_ {true};
270 
271     // Mark if the event queue is finished.
272     bool finished_ {true};
273 
274     // IO waiter used to block if no events while calling 'GetEvent'.
275     std::shared_ptr<IoWaiter> ioWaiter_;
276 
277     // File descriptor listeners to handle IO events.
278     std::map<int32_t, std::shared_ptr<FileDescriptorListener>> listeners_;
279 
280     // current running event info
281     CurrentRunningEvent currentRunningEvent_;
282 };
283 }  // namespace AppExecFwk
284 }  // namespace OHOS
285 
286 #endif  // #ifndef BASE_EVENTHANDLER_INTERFACES_INNER_API_EVENT_QUEUE_H
287