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