• 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 #include "event_queue.h"
17 
18 #include <algorithm>
19 
20 #include "epoll_io_waiter.h"
21 #include "event_handler.h"
22 #include "event_handler_utils.h"
23 #include "none_io_waiter.h"
24 
25 DEFINE_HILOG_LABEL("EventQueue");
26 
27 namespace OHOS {
28 namespace AppExecFwk {
29 namespace {
30 // Help to insert events into the event queue sorted by handle time.
InsertEventsLocked(std::list<InnerEvent::Pointer> & events,InnerEvent::Pointer & event)31 inline void InsertEventsLocked(std::list<InnerEvent::Pointer> &events, InnerEvent::Pointer &event)
32 {
33     auto f = [](const InnerEvent::Pointer &first, const InnerEvent::Pointer &second) {
34         if (!first || !second) {
35             return false;
36         }
37         return first->GetHandleTime() < second->GetHandleTime();
38     };
39     auto it = std::upper_bound(events.begin(), events.end(), event, f);
40     events.insert(it, std::move(event));
41 }
42 
43 // Help to remove file descriptor listeners.
44 template<typename T>
RemoveFileDescriptorListenerLocked(std::map<int32_t,std::shared_ptr<FileDescriptorListener>> & listeners,const std::shared_ptr<IoWaiter> & ioWaiter,const T & filter)45 void RemoveFileDescriptorListenerLocked(std::map<int32_t, std::shared_ptr<FileDescriptorListener>> &listeners,
46     const std::shared_ptr<IoWaiter> &ioWaiter, const T &filter)
47 {
48     if (!ioWaiter) {
49         return;
50     }
51     for (auto it = listeners.begin(); it != listeners.end();) {
52         if (filter(it->second)) {
53             ioWaiter->RemoveFileDescriptor(it->first);
54             it = listeners.erase(it);
55         } else {
56             ++it;
57         }
58     }
59 }
60 
61 // Help to check whether there is a valid event in list and update wake up time.
CheckEventInListLocked(const std::list<InnerEvent::Pointer> & events,const InnerEvent::TimePoint & now,InnerEvent::TimePoint & nextWakeUpTime)62 inline bool CheckEventInListLocked(const std::list<InnerEvent::Pointer> &events, const InnerEvent::TimePoint &now,
63     InnerEvent::TimePoint &nextWakeUpTime)
64 {
65     if (!events.empty()) {
66         const auto &handleTime = events.front()->GetHandleTime();
67         if (handleTime < nextWakeUpTime) {
68             nextWakeUpTime = handleTime;
69             return handleTime <= now;
70         }
71     }
72 
73     return false;
74 }
75 
PopFrontEventFromListLocked(std::list<InnerEvent::Pointer> & events)76 inline InnerEvent::Pointer PopFrontEventFromListLocked(std::list<InnerEvent::Pointer> &events)
77 {
78     InnerEvent::Pointer event = std::move(events.front());
79     events.pop_front();
80     return event;
81 }
82 }  // unnamed namespace
83 
EventQueue()84 EventQueue::EventQueue() : ioWaiter_(std::make_shared<NoneIoWaiter>())
85 {}
86 
EventQueue(const std::shared_ptr<IoWaiter> & ioWaiter)87 EventQueue::EventQueue(const std::shared_ptr<IoWaiter> &ioWaiter)
88     : ioWaiter_(ioWaiter ? ioWaiter : std::make_shared<NoneIoWaiter>())
89 {
90     if (ioWaiter_->SupportListeningFileDescriptor()) {
91         // Set callback to handle events from file descriptors.
92         ioWaiter_->SetFileDescriptorEventCallback(
93             std::bind(&EventQueue::HandleFileDescriptorEvent, this, std::placeholders::_1, std::placeholders::_2));
94     }
95 }
96 
~EventQueue()97 EventQueue::~EventQueue()
98 {
99     std::lock_guard<std::mutex> lock(queueLock_);
100     usable_.store(false);
101 }
102 
Insert(InnerEvent::Pointer & event,Priority priority)103 void EventQueue::Insert(InnerEvent::Pointer &event, Priority priority)
104 {
105     if (!event) {
106         HILOGE("Insert: Could not insert an invalid event");
107         return;
108     }
109 
110     std::lock_guard<std::mutex> lock(queueLock_);
111     if (!usable_.load()) {
112         return;
113     }
114     bool needNotify = false;
115     switch (priority) {
116         case Priority::IMMEDIATE:
117         case Priority::HIGH:
118         case Priority::LOW: {
119             needNotify = (event->GetHandleTime() < wakeUpTime_);
120             InsertEventsLocked(subEventQueues_[static_cast<uint32_t>(priority)].queue, event);
121             break;
122         }
123         case Priority::IDLE: {
124             // Never wake up thread if insert an idle event.
125             InsertEventsLocked(idleEvents_, event);
126             break;
127         }
128         default:
129             break;
130     }
131 
132     if (needNotify) {
133         ioWaiter_->NotifyOne();
134     }
135 }
136 
RemoveOrphan()137 void EventQueue::RemoveOrphan()
138 {
139     // Remove all events which lost its owner.
140     auto filter = [](const InnerEvent::Pointer &p) { return !p->GetOwner(); };
141 
142     Remove(filter);
143 
144     // Remove all listeners which lost its owner.
145     auto listenerFilter = [](const std::shared_ptr<FileDescriptorListener> &listener) {
146         if (!listener) {
147             return true;
148         }
149         return !listener->GetOwner();
150     };
151 
152     std::lock_guard<std::mutex> lock(queueLock_);
153     if (!usable_.load()) {
154         return;
155     }
156     RemoveFileDescriptorListenerLocked(listeners_, ioWaiter_, listenerFilter);
157 }
158 
159 
RemoveAll()160 void EventQueue::RemoveAll()
161 {
162     std::lock_guard<std::mutex> lock(queueLock_);
163     if (!usable_.load()) {
164         return;
165     }
166     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
167         subEventQueues_[i].queue.clear();
168     }
169     idleEvents_.clear();
170 }
171 
Remove(const std::shared_ptr<EventHandler> & owner)172 void EventQueue::Remove(const std::shared_ptr<EventHandler> &owner)
173 {
174     if (!owner) {
175         HILOGE("Remove: Invalid owner");
176         return;
177     }
178 
179     auto filter = [&owner](const InnerEvent::Pointer &p) { return (p->GetOwner() == owner); };
180 
181     Remove(filter);
182 }
183 
Remove(const std::shared_ptr<EventHandler> & owner,uint32_t innerEventId)184 void EventQueue::Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId)
185 {
186     if (!owner) {
187         HILOGE("Remove: Invalid owner");
188         return;
189     }
190 
191     auto filter = [&owner, innerEventId](const InnerEvent::Pointer &p) {
192         return (!p->HasTask()) && (p->GetOwner() == owner) && (p->GetInnerEventId() == innerEventId);
193     };
194 
195     Remove(filter);
196 }
197 
Remove(const std::shared_ptr<EventHandler> & owner,uint32_t innerEventId,int64_t param)198 void EventQueue::Remove(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId, int64_t param)
199 {
200     if (!owner) {
201         HILOGE("Remove: Invalid owner");
202         return;
203     }
204 
205     auto filter = [&owner, innerEventId, param](const InnerEvent::Pointer &p) {
206         return (!p->HasTask()) && (p->GetOwner() == owner) && (p->GetInnerEventId() == innerEventId) &&
207                (p->GetParam() == param);
208     };
209 
210     Remove(filter);
211 }
212 
Remove(const std::shared_ptr<EventHandler> & owner,const std::string & name)213 void EventQueue::Remove(const std::shared_ptr<EventHandler> &owner, const std::string &name)
214 {
215     if ((!owner) || (name.empty())) {
216         HILOGE("Remove: Invalid owner or task name");
217         return;
218     }
219 
220     auto filter = [&owner, &name](const InnerEvent::Pointer &p) {
221         return (p->HasTask()) && (p->GetOwner() == owner) && (p->GetTaskName() == name);
222     };
223 
224     Remove(filter);
225 }
226 
Remove(const RemoveFilter & filter)227 void EventQueue::Remove(const RemoveFilter &filter)
228 {
229     std::lock_guard<std::mutex> lock(queueLock_);
230     if (!usable_.load()) {
231         return;
232     }
233     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
234         subEventQueues_[i].queue.remove_if(filter);
235     }
236     idleEvents_.remove_if(filter);
237 }
238 
HasInnerEvent(const std::shared_ptr<EventHandler> & owner,uint32_t innerEventId)239 bool EventQueue::HasInnerEvent(const std::shared_ptr<EventHandler> &owner, uint32_t innerEventId)
240 {
241     if (!owner) {
242         HILOGE("HasInnerEvent: Invalid owner");
243         return false;
244     }
245     auto filter = [&owner, innerEventId](const InnerEvent::Pointer &p) {
246         return (!p->HasTask()) && (p->GetOwner() == owner) && (p->GetInnerEventId() == innerEventId);
247     };
248     return HasInnerEvent(filter);
249 }
250 
HasInnerEvent(const std::shared_ptr<EventHandler> & owner,int64_t param)251 bool EventQueue::HasInnerEvent(const std::shared_ptr<EventHandler> &owner, int64_t param)
252 {
253     if (!owner) {
254         HILOGE("HasInnerEvent: Invalid owner");
255         return false;
256     }
257     auto filter = [&owner, param](const InnerEvent::Pointer &p) {
258         return (!p->HasTask()) && (p->GetOwner() == owner) && (p->GetParam() == param);
259     };
260     return HasInnerEvent(filter);
261 }
262 
HasInnerEvent(const HasFilter & filter)263 bool EventQueue::HasInnerEvent(const HasFilter &filter)
264 {
265     std::lock_guard<std::mutex> lock(queueLock_);
266     if (!usable_.load()) {
267         return false;
268     }
269     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
270         std::list<InnerEvent::Pointer>::iterator iter =
271             std::find_if(subEventQueues_[i].queue.begin(), subEventQueues_[i].queue.end(), filter);
272         if (iter != subEventQueues_[i].queue.end()) {
273             return true;
274         }
275     }
276     std::list<InnerEvent::Pointer>::iterator iter = std::find_if(idleEvents_.begin(), idleEvents_.end(), filter);
277     return iter != idleEvents_.end();
278 }
279 
PickEventLocked(const InnerEvent::TimePoint & now,InnerEvent::TimePoint & nextWakeUpTime)280 InnerEvent::Pointer EventQueue::PickEventLocked(const InnerEvent::TimePoint &now, InnerEvent::TimePoint &nextWakeUpTime)
281 {
282     uint32_t priorityIndex = SUB_EVENT_QUEUE_NUM;
283     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
284         // Check whether any event need to be distributed.
285         if (!CheckEventInListLocked(subEventQueues_[i].queue, now, nextWakeUpTime)) {
286             continue;
287         }
288 
289         // Check whether any event in higher priority need to be distributed.
290         if (priorityIndex < SUB_EVENT_QUEUE_NUM) {
291             SubEventQueue &subQueue = subEventQueues_[priorityIndex];
292             // Check whether enough events in higher priority queue are handled continuously.
293             if (subQueue.handledEventsCount < subQueue.maxHandledEventsCount) {
294                 subQueue.handledEventsCount++;
295                 break;
296             }
297         }
298 
299         // Try to pick event from this queue.
300         priorityIndex = i;
301     }
302 
303     if (priorityIndex >= SUB_EVENT_QUEUE_NUM) {
304         // If not found any event to distribute, return nullptr.
305         return InnerEvent::Pointer(nullptr, nullptr);
306     }
307 
308     // Reset handled event count for sub event queues in higher priority.
309     for (uint32_t i = 0; i < priorityIndex; ++i) {
310         subEventQueues_[i].handledEventsCount = 0;
311     }
312 
313     return PopFrontEventFromListLocked(subEventQueues_[priorityIndex].queue);
314 }
315 
GetExpiredEventLocked(InnerEvent::TimePoint & nextExpiredTime)316 InnerEvent::Pointer EventQueue::GetExpiredEventLocked(InnerEvent::TimePoint &nextExpiredTime)
317 {
318     auto now = InnerEvent::Clock::now();
319     wakeUpTime_ = InnerEvent::TimePoint::max();
320     // Find an event which could be distributed right now.
321     InnerEvent::Pointer event = PickEventLocked(now, wakeUpTime_);
322     if (event) {
323         // Exit idle mode, if found an event to distribute.
324         isIdle_ = false;
325         return event;
326     }
327 
328     // If found nothing, enter idle mode and make a time stamp.
329     if (!isIdle_) {
330         idleTimeStamp_ = now;
331         isIdle_ = true;
332     }
333 
334     if (!idleEvents_.empty()) {
335         const auto &idleEvent = idleEvents_.front();
336 
337         // Return the idle event that has been sent before time stamp and reaches its handle time.
338         if ((idleEvent->GetSendTime() <= idleTimeStamp_) && (idleEvent->GetHandleTime() <= now)) {
339             return PopFrontEventFromListLocked(idleEvents_);
340         }
341     }
342 
343     // Update wake up time.
344     nextExpiredTime = wakeUpTime_;
345     return InnerEvent::Pointer(nullptr, nullptr);
346 }
347 
GetEvent()348 InnerEvent::Pointer EventQueue::GetEvent()
349 {
350     std::unique_lock<std::mutex> lock(queueLock_);
351     while (!finished_) {
352         InnerEvent::TimePoint nextWakeUpTime = InnerEvent::TimePoint::max();
353         InnerEvent::Pointer event = GetExpiredEventLocked(nextWakeUpTime);
354         if (event) {
355             return event;
356         }
357         WaitUntilLocked(nextWakeUpTime, lock);
358     }
359 
360     HILOGD("GetEvent: Break out");
361     return InnerEvent::Pointer(nullptr, nullptr);
362 }
363 
GetExpiredEvent(InnerEvent::TimePoint & nextExpiredTime)364 InnerEvent::Pointer EventQueue::GetExpiredEvent(InnerEvent::TimePoint &nextExpiredTime)
365 {
366     std::unique_lock<std::mutex> lock(queueLock_);
367     return GetExpiredEventLocked(nextExpiredTime);
368 }
369 
AddFileDescriptorListener(int32_t fileDescriptor,uint32_t events,const std::shared_ptr<FileDescriptorListener> & listener)370 ErrCode EventQueue::AddFileDescriptorListener(
371     int32_t fileDescriptor, uint32_t events, const std::shared_ptr<FileDescriptorListener> &listener)
372 {
373     if ((fileDescriptor < 0) || ((events & FILE_DESCRIPTOR_EVENTS_MASK) == 0) || (!listener)) {
374         HILOGE("AddFileDescriptorListener(%{public}d, %{public}u, %{public}s): Invalid parameter",
375             fileDescriptor,
376             events,
377             listener ? "valid" : "null");
378         return EVENT_HANDLER_ERR_INVALID_PARAM;
379     }
380 
381     std::lock_guard<std::mutex> lock(queueLock_);
382     if (!usable_.load()) {
383         return EVENT_HANDLER_ERR_NO_EVENT_RUNNER;
384     }
385     auto it = listeners_.find(fileDescriptor);
386     if (it != listeners_.end()) {
387         HILOGE("AddFileDescriptorListener: File descriptor %{public}d is already in listening", fileDescriptor);
388         return EVENT_HANDLER_ERR_FD_ALREADY;
389     }
390 
391     if (!EnsureIoWaiterSupportListerningFileDescriptorLocked()) {
392         return EVENT_HANDLER_ERR_FD_NOT_SUPPORT;
393     }
394 
395     if (!ioWaiter_->AddFileDescriptor(fileDescriptor, events)) {
396         HILOGE("AddFileDescriptorListener: Failed to add file descriptor into IO waiter");
397         return EVENT_HANDLER_ERR_FD_FAILED;
398     }
399 
400     listeners_.emplace(fileDescriptor, listener);
401     return ERR_OK;
402 }
403 
RemoveFileDescriptorListener(const std::shared_ptr<EventHandler> & owner)404 void EventQueue::RemoveFileDescriptorListener(const std::shared_ptr<EventHandler> &owner)
405 {
406     if (!owner) {
407         HILOGE("RemoveFileDescriptorListener: Invalid owner");
408         return;
409     }
410 
411     auto listenerFilter = [&owner](const std::shared_ptr<FileDescriptorListener> &listener) {
412         if (!listener) {
413             return false;
414         }
415         return listener->GetOwner() == owner;
416     };
417 
418     std::lock_guard<std::mutex> lock(queueLock_);
419     if (!usable_.load()) {
420         return;
421     }
422     RemoveFileDescriptorListenerLocked(listeners_, ioWaiter_, listenerFilter);
423 }
424 
RemoveFileDescriptorListener(int32_t fileDescriptor)425 void EventQueue::RemoveFileDescriptorListener(int32_t fileDescriptor)
426 {
427     if (fileDescriptor < 0) {
428         HILOGE("RemoveFileDescriptorListener(%{public}d): Invalid file descriptor", fileDescriptor);
429         return;
430     }
431 
432     std::lock_guard<std::mutex> lock(queueLock_);
433     if (!usable_.load()) {
434         return;
435     }
436     if (listeners_.erase(fileDescriptor) > 0) {
437         ioWaiter_->RemoveFileDescriptor(fileDescriptor);
438     }
439 }
440 
Prepare()441 void EventQueue::Prepare()
442 {
443     std::lock_guard<std::mutex> lock(queueLock_);
444     if (!usable_.load()) {
445         return;
446     }
447     finished_ = false;
448 }
449 
Finish()450 void EventQueue::Finish()
451 {
452     std::lock_guard<std::mutex> lock(queueLock_);
453     if (!usable_.load()) {
454         return;
455     }
456     finished_ = true;
457     ioWaiter_->NotifyAll();
458 }
459 
WaitUntilLocked(const InnerEvent::TimePoint & when,std::unique_lock<std::mutex> & lock)460 void EventQueue::WaitUntilLocked(const InnerEvent::TimePoint &when, std::unique_lock<std::mutex> &lock)
461 {
462     // Get a temp reference of IO waiter, otherwise it maybe released while waiting.
463     auto ioWaiterHolder = ioWaiter_;
464     if (!ioWaiterHolder->WaitFor(lock, TimePointToTimeOut(when))) {
465         HILOGE("WaitUntilLocked: Failed to call wait, reset IO waiter");
466         ioWaiter_ = std::make_shared<NoneIoWaiter>();
467         listeners_.clear();
468     }
469 }
470 
HandleFileDescriptorEvent(int32_t fileDescriptor,uint32_t events)471 void EventQueue::HandleFileDescriptorEvent(int32_t fileDescriptor, uint32_t events)
472 {
473     std::shared_ptr<FileDescriptorListener> listener;
474 
475     {
476         std::lock_guard<std::mutex> lock(queueLock_);
477         if (!usable_.load()) {
478             return;
479         }
480         auto it = listeners_.find(fileDescriptor);
481         if (it == listeners_.end()) {
482             HILOGW("HandleFileDescriptorEvent: Can not found listener, maybe it is removed");
483             return;
484         }
485 
486         // Hold instance of listener.
487         listener = it->second;
488         if (!listener) {
489             return;
490         }
491     }
492 
493     auto handler = listener->GetOwner();
494     if (!handler) {
495         HILOGW("HandleFileDescriptorEvent: Owner of listener is released");
496         return;
497     }
498 
499     std::weak_ptr<FileDescriptorListener> wp = listener;
500     auto f = [fileDescriptor, events, wp]() {
501         auto listener = wp.lock();
502         if (!listener) {
503             HILOGW("HandleFileDescriptorEvent-Lambda: Listener is released");
504             return;
505         }
506 
507         if ((events & FILE_DESCRIPTOR_INPUT_EVENT) != 0) {
508             listener->OnReadable(fileDescriptor);
509         }
510 
511         if ((events & FILE_DESCRIPTOR_OUTPUT_EVENT) != 0) {
512             listener->OnWritable(fileDescriptor);
513         }
514 
515         if ((events & FILE_DESCRIPTOR_SHUTDOWN_EVENT) != 0) {
516             listener->OnShutdown(fileDescriptor);
517         }
518 
519         if ((events & FILE_DESCRIPTOR_EXCEPTION_EVENT) != 0) {
520             listener->OnException(fileDescriptor);
521         }
522     };
523 
524     // Post a high priority task to handle file descriptor events.
525     handler->PostHighPriorityTask(f);
526 }
527 
EnsureIoWaiterSupportListerningFileDescriptorLocked()528 bool EventQueue::EnsureIoWaiterSupportListerningFileDescriptorLocked()
529 {
530     if (ioWaiter_->SupportListeningFileDescriptor()) {
531         return true;
532     }
533 
534     auto newIoWaiter = std::make_shared<EpollIoWaiter>();
535     if (!newIoWaiter->Init()) {
536         HILOGE("EnsureIoWaiterSupportListerningFileDescriptorLocked: Failed to initialize epoll");
537         return false;
538     }
539 
540     // Set callback to handle events from file descriptors.
541     newIoWaiter->SetFileDescriptorEventCallback(
542         std::bind(&EventQueue::HandleFileDescriptorEvent, this, std::placeholders::_1, std::placeholders::_2));
543 
544     ioWaiter_->NotifyAll();
545     ioWaiter_ = newIoWaiter;
546     return true;
547 }
548 
Dump(Dumper & dumper)549 void EventQueue::Dump(Dumper &dumper)
550 {
551     std::lock_guard<std::mutex> lock(queueLock_);
552     if (!usable_.load()) {
553         return;
554     }
555     std::string priority[] = {"Immediate", "High", "Low"};
556     uint32_t total = 0;
557     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
558         uint32_t n = 0;
559         dumper.Dump(dumper.GetTag() + " " + priority[i] + " priority event queue information:" + LINE_SEPARATOR);
560         for (auto it = subEventQueues_[i].queue.begin(); it != subEventQueues_[i].queue.end(); ++it) {
561             ++n;
562             dumper.Dump(dumper.GetTag() + " No." + std::to_string(n) + " : " + (*it)->Dump());
563             ++total;
564         }
565         dumper.Dump(
566             dumper.GetTag() + " Total size of " + priority[i] + " events : " + std::to_string(n) + LINE_SEPARATOR);
567     }
568 
569     dumper.Dump(dumper.GetTag() + " Idle priority event queue information:" + LINE_SEPARATOR);
570     int n = 0;
571     for (auto it = idleEvents_.begin(); it != idleEvents_.end(); ++it) {
572         ++n;
573         dumper.Dump(dumper.GetTag() + " No." + std::to_string(n) + " : " + (*it)->Dump());
574         ++total;
575     }
576     dumper.Dump(dumper.GetTag() + " Total size of Idle events : " + std::to_string(n) + LINE_SEPARATOR);
577 
578     dumper.Dump(dumper.GetTag() + " Total event size : " + std::to_string(total) + LINE_SEPARATOR);
579 }
580 
DumpQueueInfo(std::string & queueInfo)581 void EventQueue::DumpQueueInfo(std::string& queueInfo)
582 {
583     std::lock_guard<std::mutex> lock(queueLock_);
584     if (!usable_.load()) {
585         return;
586     }
587     std::string priority[] = {"Immediate", "High", "Low"};
588     uint32_t total = 0;
589     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
590         uint32_t n = 0;
591         queueInfo +=  "            " + priority[i] + " priority event queue:" + LINE_SEPARATOR;
592         for (auto it = subEventQueues_[i].queue.begin(); it != subEventQueues_[i].queue.end(); ++it) {
593             ++n;
594             queueInfo +=  "            No." + std::to_string(n) + " : " + (*it)->Dump();
595             ++total;
596         }
597         queueInfo +=  "              Total size of " + priority[i] + " events : " + std::to_string(n) + LINE_SEPARATOR;
598     }
599 
600     queueInfo += "            Idle priority event queue:" + LINE_SEPARATOR;
601 
602     int n = 0;
603     for (auto it = idleEvents_.begin(); it != idleEvents_.end(); ++it) {
604         ++n;
605         queueInfo += "            No." + std::to_string(n) + " : " + (*it)->Dump();
606         ++total;
607     }
608     queueInfo += "              Total size of Idle events : " + std::to_string(n) + LINE_SEPARATOR;
609 
610     queueInfo += "            Total event size : " + std::to_string(total);
611 }
612 
IsIdle()613 bool EventQueue::IsIdle()
614 {
615     return isIdle_;
616 }
617 
IsQueueEmpty()618 bool EventQueue::IsQueueEmpty()
619 {
620     std::lock_guard<std::mutex> lock(queueLock_);
621     if (!usable_.load()) {
622         return false;
623     }
624     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
625         uint32_t queueSize = subEventQueues_[i].queue.size();
626         if (queueSize != 0) {
627             return false;
628         }
629     }
630 
631     return idleEvents_.size() == 0;
632 }
633 }  // namespace AppExecFwk
634 }  // namespace OHOS
635