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