• 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         currentRunningEvent_ = CurrentRunningEvent(now, event);
326         return event;
327     }
328 
329     // If found nothing, enter idle mode and make a time stamp.
330     if (!isIdle_) {
331         idleTimeStamp_ = now;
332         isIdle_ = true;
333     }
334 
335     if (!idleEvents_.empty()) {
336         const auto &idleEvent = idleEvents_.front();
337 
338         // Return the idle event that has been sent before time stamp and reaches its handle time.
339         if ((idleEvent->GetSendTime() <= idleTimeStamp_) && (idleEvent->GetHandleTime() <= now)) {
340             event = PopFrontEventFromListLocked(idleEvents_);
341             currentRunningEvent_ = CurrentRunningEvent(now, event);
342             return event;
343         }
344     }
345 
346     // Update wake up time.
347     nextExpiredTime = wakeUpTime_;
348     currentRunningEvent_ = CurrentRunningEvent();
349     return InnerEvent::Pointer(nullptr, nullptr);
350 }
351 
GetEvent()352 InnerEvent::Pointer EventQueue::GetEvent()
353 {
354     std::unique_lock<std::mutex> lock(queueLock_);
355     while (!finished_) {
356         InnerEvent::TimePoint nextWakeUpTime = InnerEvent::TimePoint::max();
357         InnerEvent::Pointer event = GetExpiredEventLocked(nextWakeUpTime);
358         if (event) {
359             return event;
360         }
361         WaitUntilLocked(nextWakeUpTime, lock);
362     }
363 
364     HILOGD("GetEvent: Break out");
365     return InnerEvent::Pointer(nullptr, nullptr);
366 }
367 
GetExpiredEvent(InnerEvent::TimePoint & nextExpiredTime)368 InnerEvent::Pointer EventQueue::GetExpiredEvent(InnerEvent::TimePoint &nextExpiredTime)
369 {
370     std::unique_lock<std::mutex> lock(queueLock_);
371     return GetExpiredEventLocked(nextExpiredTime);
372 }
373 
AddFileDescriptorListener(int32_t fileDescriptor,uint32_t events,const std::shared_ptr<FileDescriptorListener> & listener)374 ErrCode EventQueue::AddFileDescriptorListener(
375     int32_t fileDescriptor, uint32_t events, const std::shared_ptr<FileDescriptorListener> &listener)
376 {
377     if ((fileDescriptor < 0) || ((events & FILE_DESCRIPTOR_EVENTS_MASK) == 0) || (!listener)) {
378         HILOGE("AddFileDescriptorListener(%{public}d, %{public}u, %{public}s): Invalid parameter",
379             fileDescriptor,
380             events,
381             listener ? "valid" : "null");
382         return EVENT_HANDLER_ERR_INVALID_PARAM;
383     }
384 
385     std::lock_guard<std::mutex> lock(queueLock_);
386     if (!usable_.load()) {
387         return EVENT_HANDLER_ERR_NO_EVENT_RUNNER;
388     }
389     auto it = listeners_.find(fileDescriptor);
390     if (it != listeners_.end()) {
391         HILOGE("AddFileDescriptorListener: File descriptor %{public}d is already in listening", fileDescriptor);
392         return EVENT_HANDLER_ERR_FD_ALREADY;
393     }
394 
395     if (!EnsureIoWaiterSupportListerningFileDescriptorLocked()) {
396         return EVENT_HANDLER_ERR_FD_NOT_SUPPORT;
397     }
398 
399     if (!ioWaiter_->AddFileDescriptor(fileDescriptor, events)) {
400         HILOGE("AddFileDescriptorListener: Failed to add file descriptor into IO waiter");
401         return EVENT_HANDLER_ERR_FD_FAILED;
402     }
403 
404     listeners_.emplace(fileDescriptor, listener);
405     return ERR_OK;
406 }
407 
RemoveFileDescriptorListener(const std::shared_ptr<EventHandler> & owner)408 void EventQueue::RemoveFileDescriptorListener(const std::shared_ptr<EventHandler> &owner)
409 {
410     if (!owner) {
411         HILOGE("RemoveFileDescriptorListener: Invalid owner");
412         return;
413     }
414 
415     auto listenerFilter = [&owner](const std::shared_ptr<FileDescriptorListener> &listener) {
416         if (!listener) {
417             return false;
418         }
419         return listener->GetOwner() == owner;
420     };
421 
422     std::lock_guard<std::mutex> lock(queueLock_);
423     if (!usable_.load()) {
424         return;
425     }
426     RemoveFileDescriptorListenerLocked(listeners_, ioWaiter_, listenerFilter);
427 }
428 
RemoveFileDescriptorListener(int32_t fileDescriptor)429 void EventQueue::RemoveFileDescriptorListener(int32_t fileDescriptor)
430 {
431     if (fileDescriptor < 0) {
432         HILOGE("RemoveFileDescriptorListener(%{public}d): Invalid file descriptor", fileDescriptor);
433         return;
434     }
435 
436     std::lock_guard<std::mutex> lock(queueLock_);
437     if (!usable_.load()) {
438         return;
439     }
440     if (listeners_.erase(fileDescriptor) > 0) {
441         ioWaiter_->RemoveFileDescriptor(fileDescriptor);
442     }
443 }
444 
Prepare()445 void EventQueue::Prepare()
446 {
447     std::lock_guard<std::mutex> lock(queueLock_);
448     if (!usable_.load()) {
449         return;
450     }
451     finished_ = false;
452 }
453 
Finish()454 void EventQueue::Finish()
455 {
456     std::lock_guard<std::mutex> lock(queueLock_);
457     if (!usable_.load()) {
458         return;
459     }
460     finished_ = true;
461     ioWaiter_->NotifyAll();
462 }
463 
WaitUntilLocked(const InnerEvent::TimePoint & when,std::unique_lock<std::mutex> & lock)464 void EventQueue::WaitUntilLocked(const InnerEvent::TimePoint &when, std::unique_lock<std::mutex> &lock)
465 {
466     // Get a temp reference of IO waiter, otherwise it maybe released while waiting.
467     auto ioWaiterHolder = ioWaiter_;
468     if (!ioWaiterHolder->WaitFor(lock, TimePointToTimeOut(when))) {
469         HILOGE("WaitUntilLocked: Failed to call wait, reset IO waiter");
470         ioWaiter_ = std::make_shared<NoneIoWaiter>();
471         listeners_.clear();
472     }
473 }
474 
HandleFileDescriptorEvent(int32_t fileDescriptor,uint32_t events)475 void EventQueue::HandleFileDescriptorEvent(int32_t fileDescriptor, uint32_t events)
476 {
477     std::shared_ptr<FileDescriptorListener> listener;
478 
479     {
480         std::lock_guard<std::mutex> lock(queueLock_);
481         if (!usable_.load()) {
482             return;
483         }
484         auto it = listeners_.find(fileDescriptor);
485         if (it == listeners_.end()) {
486             HILOGW("HandleFileDescriptorEvent: Can not found listener, maybe it is removed");
487             return;
488         }
489 
490         // Hold instance of listener.
491         listener = it->second;
492         if (!listener) {
493             return;
494         }
495     }
496 
497     auto handler = listener->GetOwner();
498     if (!handler) {
499         HILOGW("HandleFileDescriptorEvent: Owner of listener is released");
500         return;
501     }
502 
503     std::weak_ptr<FileDescriptorListener> wp = listener;
504     auto f = [fileDescriptor, events, wp]() {
505         auto listener = wp.lock();
506         if (!listener) {
507             HILOGW("HandleFileDescriptorEvent-Lambda: Listener is released");
508             return;
509         }
510 
511         if ((events & FILE_DESCRIPTOR_INPUT_EVENT) != 0) {
512             listener->OnReadable(fileDescriptor);
513         }
514 
515         if ((events & FILE_DESCRIPTOR_OUTPUT_EVENT) != 0) {
516             listener->OnWritable(fileDescriptor);
517         }
518 
519         if ((events & FILE_DESCRIPTOR_SHUTDOWN_EVENT) != 0) {
520             listener->OnShutdown(fileDescriptor);
521         }
522 
523         if ((events & FILE_DESCRIPTOR_EXCEPTION_EVENT) != 0) {
524             listener->OnException(fileDescriptor);
525         }
526     };
527 
528     // Post a high priority task to handle file descriptor events.
529     handler->PostHighPriorityTask(f);
530 }
531 
EnsureIoWaiterSupportListerningFileDescriptorLocked()532 bool EventQueue::EnsureIoWaiterSupportListerningFileDescriptorLocked()
533 {
534     if (ioWaiter_->SupportListeningFileDescriptor()) {
535         return true;
536     }
537 
538     auto newIoWaiter = std::make_shared<EpollIoWaiter>();
539     if (!newIoWaiter->Init()) {
540         HILOGE("EnsureIoWaiterSupportListerningFileDescriptorLocked: Failed to initialize epoll");
541         return false;
542     }
543 
544     // Set callback to handle events from file descriptors.
545     newIoWaiter->SetFileDescriptorEventCallback(
546         std::bind(&EventQueue::HandleFileDescriptorEvent, this, std::placeholders::_1, std::placeholders::_2));
547 
548     ioWaiter_->NotifyAll();
549     ioWaiter_ = newIoWaiter;
550     return true;
551 }
552 
DumpCurrentRunning()553 std::string EventQueue::DumpCurrentRunning()
554 {
555     std::string content;
556     if (currentRunningEvent_.beginTime_ == InnerEvent::TimePoint::max()) {
557         content.append("{}");
558     } else {
559         content.append("start at " + InnerEvent::DumpTimeToString(currentRunningEvent_.beginTime_) + ", ");
560         content.append("Event { ");
561         if (!currentRunningEvent_.owner_.expired()) {
562             content.append("send thread = " + std::to_string(currentRunningEvent_.senderKernelThreadId_));
563             content.append(", send time = " + InnerEvent::DumpTimeToString(currentRunningEvent_.sendTime_));
564             content.append(", handle time = " + InnerEvent::DumpTimeToString(currentRunningEvent_.handleTime_));
565             if (currentRunningEvent_.hasTask_) {
566                 content.append(", task name = " + currentRunningEvent_.taskName_);
567             } else {
568                 content.append(", id = " + std::to_string(currentRunningEvent_.innerEventId_));
569             }
570             if (currentRunningEvent_.param_ != 0) {
571                 content.append(", param = " + std::to_string(currentRunningEvent_.param_));
572             }
573         } else {
574             content.append("No handler");
575         }
576         content.append(" }");
577     }
578 
579     return content;
580 }
581 
Dump(Dumper & dumper)582 void EventQueue::Dump(Dumper &dumper)
583 {
584     std::lock_guard<std::mutex> lock(queueLock_);
585     if (!usable_.load()) {
586         return;
587     }
588 
589     dumper.Dump(dumper.GetTag() + " Current Running: " + DumpCurrentRunning() + LINE_SEPARATOR);
590     std::string priority[] = {"Immediate", "High", "Low"};
591     uint32_t total = 0;
592     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
593         uint32_t n = 0;
594         dumper.Dump(dumper.GetTag() + " " + priority[i] + " priority event queue information:" + LINE_SEPARATOR);
595         for (auto it = subEventQueues_[i].queue.begin(); it != subEventQueues_[i].queue.end(); ++it) {
596             ++n;
597             dumper.Dump(dumper.GetTag() + " No." + std::to_string(n) + " : " + (*it)->Dump());
598             ++total;
599         }
600         dumper.Dump(
601             dumper.GetTag() + " Total size of " + priority[i] + " events : " + std::to_string(n) + LINE_SEPARATOR);
602     }
603 
604     dumper.Dump(dumper.GetTag() + " Idle priority event queue information:" + LINE_SEPARATOR);
605     int n = 0;
606     for (auto it = idleEvents_.begin(); it != idleEvents_.end(); ++it) {
607         ++n;
608         dumper.Dump(dumper.GetTag() + " No." + std::to_string(n) + " : " + (*it)->Dump());
609         ++total;
610     }
611     dumper.Dump(dumper.GetTag() + " Total size of Idle events : " + std::to_string(n) + LINE_SEPARATOR);
612 
613     dumper.Dump(dumper.GetTag() + " Total event size : " + std::to_string(total) + LINE_SEPARATOR);
614 }
615 
DumpQueueInfo(std::string & queueInfo)616 void EventQueue::DumpQueueInfo(std::string& queueInfo)
617 {
618     std::lock_guard<std::mutex> lock(queueLock_);
619     if (!usable_.load()) {
620         return;
621     }
622     std::string priority[] = {"Immediate", "High", "Low"};
623     uint32_t total = 0;
624     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
625         uint32_t n = 0;
626         queueInfo +=  "            " + priority[i] + " priority event queue:" + LINE_SEPARATOR;
627         for (auto it = subEventQueues_[i].queue.begin(); it != subEventQueues_[i].queue.end(); ++it) {
628             ++n;
629             queueInfo +=  "            No." + std::to_string(n) + " : " + (*it)->Dump();
630             ++total;
631         }
632         queueInfo +=  "              Total size of " + priority[i] + " events : " + std::to_string(n) + LINE_SEPARATOR;
633     }
634 
635     queueInfo += "            Idle priority event queue:" + LINE_SEPARATOR;
636 
637     int n = 0;
638     for (auto it = idleEvents_.begin(); it != idleEvents_.end(); ++it) {
639         ++n;
640         queueInfo += "            No." + std::to_string(n) + " : " + (*it)->Dump();
641         ++total;
642     }
643     queueInfo += "              Total size of Idle events : " + std::to_string(n) + LINE_SEPARATOR;
644 
645     queueInfo += "            Total event size : " + std::to_string(total);
646 }
647 
IsIdle()648 bool EventQueue::IsIdle()
649 {
650     return isIdle_;
651 }
652 
IsQueueEmpty()653 bool EventQueue::IsQueueEmpty()
654 {
655     std::lock_guard<std::mutex> lock(queueLock_);
656     if (!usable_.load()) {
657         return false;
658     }
659     for (uint32_t i = 0; i < SUB_EVENT_QUEUE_NUM; ++i) {
660         uint32_t queueSize = subEventQueues_[i].queue.size();
661         if (queueSize != 0) {
662             return false;
663         }
664     }
665 
666     return idleEvents_.size() == 0;
667 }
668 
CurrentRunningEvent()669 CurrentRunningEvent::CurrentRunningEvent()
670 {
671     beginTime_ = InnerEvent::TimePoint::max();
672 }
673 
CurrentRunningEvent(InnerEvent::TimePoint time,InnerEvent::Pointer & event)674 CurrentRunningEvent::CurrentRunningEvent(InnerEvent::TimePoint time, InnerEvent::Pointer &event)
675 {
676     beginTime_ = time;
677     owner_ = event->GetOwner();
678     senderKernelThreadId_ = event->GetSenderKernelThreadId();
679     sendTime_ = event->GetSendTime();
680     handleTime_ = event->GetHandleTime();
681     param_ = event->GetParam();
682     if (event->HasTask()) {
683         hasTask_ = true;
684         taskName_ = event->GetTaskName();
685     } else {
686         innerEventId_ = event->GetInnerEventId();
687     }
688 }
689 
690 }  // namespace AppExecFwk
691 }  // namespace OHOS
692