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