1 /*
2 * Copyright (c) 2021-2023 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_handler.h"
17
18 #include <unistd.h>
19 #include <sys/syscall.h>
20 #include "event_handler_utils.h"
21 #include "event_logger.h"
22 #ifdef HAS_HICHECKER_NATIVE_PART
23 #include "hichecker.h"
24 #endif // HAS_HICHECKER_NATIVE_PART
25 #ifdef FFRT_USAGE_ENABLE
26 #include "ffrt_inner.h"
27 #endif // FFRT_USAGE_ENABLE
28 #include "thread_local_data.h"
29 #include "event_hitrace_meter_adapter.h"
30 #include "ffrt_descriptor_listener.h"
31
32 using namespace OHOS::HiviewDFX;
33 namespace OHOS {
34 namespace AppExecFwk {
35 namespace {
36 static constexpr int FFRT_SUCCESS = 0;
37 static constexpr int FFRT_ERROR = -1;
38 static constexpr int FFRT_TASK_REMOVE_FAIL = 1;
39 DEFINE_EH_HILOG_LABEL("EventHandler");
40 }
41 thread_local std::weak_ptr<EventHandler> EventHandler::currentEventHandler;
42
Current()43 std::shared_ptr<EventHandler> EventHandler::Current()
44 {
45 #ifdef FFRT_USAGE_ENABLE
46 if (ffrt_this_task_get_id()) {
47 auto handler = ffrt_get_current_queue_eventhandler();
48 if (handler == nullptr) {
49 HILOGW("Current handler is null.");
50 return nullptr;
51 }
52 return *(reinterpret_cast<std::shared_ptr<EventHandler>*>(handler));
53 } else {
54 return currentEventHandler.lock();
55 }
56 #else
57 return currentEventHandler.lock();
58 #endif
59 }
60
EventHandler(const std::shared_ptr<EventRunner> & runner)61 EventHandler::EventHandler(const std::shared_ptr<EventRunner> &runner) : eventRunner_(runner)
62 {
63 static std::atomic<uint64_t> handlerCount = 1;
64 handlerId_ = std::to_string(handlerCount.load()) + "_" + std::to_string(GetTimeStamp());
65 handlerCount.fetch_add(1);
66 EH_LOGI_LIMIT("Create eventHandler %{public}s", handlerId_.c_str());
67 }
68
~EventHandler()69 EventHandler::~EventHandler()
70 {
71 HILOGI("~EventHandler enter %{public}s", handlerId_.c_str());
72 if (eventRunner_) {
73 HILOGD("eventRunner is alive");
74 /*
75 * This handler is finishing, need to remove all events belong to it.
76 * But events only have weak pointer of this handler,
77 * now weak pointer is invalid, so these events become orphans.
78 */
79 #ifdef FFRT_USAGE_ENABLE
80 if (eventRunner_->threadMode_ == ThreadMode::FFRT) {
81 eventRunner_->GetEventQueue()->RemoveOrphanByHandlerId(handlerId_);
82 } else {
83 eventRunner_->GetEventQueue()->RemoveOrphan();
84 }
85 #else
86 eventRunner_->GetEventQueue()->RemoveOrphan();
87 #endif
88 }
89 }
90
SendEvent(InnerEvent::Pointer & event,int64_t delayTime,Priority priority)91 bool EventHandler::SendEvent(InnerEvent::Pointer &event, int64_t delayTime, Priority priority)
92 {
93 if (!event) {
94 HILOGE("Could not send an invalid event");
95 return false;
96 }
97
98 if (!eventRunner_) {
99 HILOGE("MUST Set event runner before sending events");
100 return false;
101 }
102
103 InnerEvent::TimePoint now = InnerEvent::Clock::now();
104 event->SetSendTime(now);
105 event->SetSenderKernelThreadId(getproctid());
106 event->SetEventUniqueId();
107 if (delayTime > 0) {
108 event->SetHandleTime(now + std::chrono::milliseconds(delayTime));
109 } else {
110 event->SetHandleTime(now);
111 }
112 event->SetOwnerId(handlerId_);
113 event->SetDelayTime(delayTime);
114 event->SetOwner(shared_from_this());
115 // get traceId from event, if HiTraceChain::begin has been called, would get a valid trace id.
116 auto traceId = event->GetOrCreateTraceId();
117 // if traceId is valid, out put trace information
118 if (AllowHiTraceOutPut(traceId, event->HasWaiter())) {
119 HiTracePointerOutPut(traceId, event, "Send", HiTraceTracepointType::HITRACE_TP_CS);
120 }
121 HILOGD("Current event id is %{public}s .", (event->GetEventUniqueId()).c_str());
122 eventRunner_->GetEventQueue()->Insert(event, priority);
123 return true;
124 }
125
PostTaskAtFront(const Callback & callback,const std::string & name,Priority priority,const Caller & caller)126 bool EventHandler::PostTaskAtFront(const Callback &callback, const std::string &name, Priority priority,
127 const Caller &caller)
128 {
129 if (!eventRunner_) {
130 HILOGE("MUST Set event runner before posting events");
131 return false;
132 }
133
134 auto event = InnerEvent::Get(callback, name, caller);
135 if (!event) {
136 HILOGE("Get an invalid event");
137 return false;
138 }
139
140 event->SetDelayTime(0);
141 event->SetOwnerId(handlerId_);
142 InnerEvent::TimePoint now = InnerEvent::Clock::now();
143 event->SetSendTime(now);
144 event->SetHandleTime(now);
145 event->SetSenderKernelThreadId(getproctid());
146 event->SetEventUniqueId();
147 event->SetOwner(shared_from_this());
148 auto traceId = event->GetOrCreateTraceId();
149 if (AllowHiTraceOutPut(traceId, event->HasWaiter())) {
150 HiTracePointerOutPut(traceId, event, "Send", HiTraceTracepointType::HITRACE_TP_CS);
151 }
152 HILOGD("Current front event id is %{public}s .", (event->GetEventUniqueId()).c_str());
153 eventRunner_->GetEventQueue()->Insert(event, priority, EventInsertType::AT_FRONT);
154 return true;
155 }
156
SendTimingEvent(InnerEvent::Pointer & event,int64_t taskTime,Priority priority)157 bool EventHandler::SendTimingEvent(InnerEvent::Pointer &event, int64_t taskTime, Priority priority)
158 {
159 InnerEvent::TimePoint nowSys = InnerEvent::Clock::now();
160 auto epoch = nowSys.time_since_epoch();
161 long nowSysTime = std::chrono::duration_cast<std::chrono::milliseconds>(epoch).count();
162 int64_t delayTime = taskTime - nowSysTime;
163 if (delayTime < 0) {
164 HILOGW("SendTime is before now systime, change to 0 delaytime Event");
165 return SendEvent(event, 0, priority);
166 }
167
168 return SendEvent(event, delayTime, priority);
169 }
170
SendSyncEvent(InnerEvent::Pointer & event,Priority priority)171 bool EventHandler::SendSyncEvent(InnerEvent::Pointer &event, Priority priority)
172 {
173 if ((!event) || (priority == Priority::IDLE)) {
174 HILOGE("Could not send an invalid event or idle event");
175 return false;
176 }
177
178 if ((!eventRunner_) || (!eventRunner_->IsRunning())) {
179 HILOGE("MUST Set a running event runner before sending sync events");
180 return false;
181 }
182
183 #ifdef FFRT_USAGE_ENABLE
184 if ((ffrt_this_task_get_id() && eventRunner_->threadMode_ == ThreadMode::FFRT) ||
185 eventRunner_ == EventRunner::Current()) {
186 DistributeEvent(event);
187 return true;
188 }
189
190 // get traceId from event, if HiTraceChain::begin has been called, would get a valid trace id.
191 auto spanId = event->GetOrCreateTraceId();
192
193 if (eventRunner_->threadMode_ == ThreadMode::FFRT) {
194 event->SetSendTime(InnerEvent::Clock::now());
195 event->SetEventUniqueId();
196 event->SetHandleTime(InnerEvent::Clock::now());
197 event->SetOwnerId(handlerId_);
198 event->SetDelayTime(0);
199 event->SetOwner(shared_from_this());
200 eventRunner_->GetEventQueue()->InsertSyncEvent(event, priority);
201 } else {
202 // Create waiter, used to block.
203 auto waiter = event->CreateWaiter();
204 // Send this event as normal one.
205 if (!SendEvent(event, 0, priority)) {
206 HILOGE("SendEvent is failed");
207 return false;
208 }
209 // Wait until event is processed(recycled).
210 waiter->Wait();
211 }
212 #else
213 // If send a sync event in same event runner, distribute here.
214 if (eventRunner_ == EventRunner::Current()) {
215 DistributeEvent(event);
216 return true;
217 }
218
219 // get traceId from event, if HiTraceChain::begin has been called, would get a valid trace id.
220 auto spanId = event->GetOrCreateTraceId();
221
222 // Create waiter, used to block.
223 auto waiter = event->CreateWaiter();
224 // Send this event as normal one.
225 if (!SendEvent(event, 0, priority)) {
226 HILOGE("SendEvent is failed");
227 return false;
228 }
229 // Wait until event is processed(recycled).
230 waiter->Wait();
231 #endif
232 if ((spanId) && (spanId->IsValid())) {
233 HiTraceChain::Tracepoint(HiTraceTracepointType::HITRACE_TP_CR, *spanId, "event is processed");
234 }
235
236 return true;
237 }
238
RemoveAllEvents()239 void EventHandler::RemoveAllEvents()
240 {
241 HILOGD("RemoveAllEvents enter");
242 if (!eventRunner_) {
243 HILOGE("MUST Set event runner before removing all events");
244 return;
245 }
246
247 eventRunner_->GetEventQueue()->Remove(shared_from_this());
248 }
249
RemoveEvent(uint32_t innerEventId)250 void EventHandler::RemoveEvent(uint32_t innerEventId)
251 {
252 HILOGD("RemoveEvent enter");
253 if (!eventRunner_) {
254 HILOGE("MUST Set event runner before removing events by id");
255 return;
256 }
257
258 eventRunner_->GetEventQueue()->Remove(shared_from_this(), innerEventId);
259 }
260
RemoveEvent(uint32_t innerEventId,int64_t param)261 void EventHandler::RemoveEvent(uint32_t innerEventId, int64_t param)
262 {
263 HILOGD("RemoveEvent -- enter");
264 if (!eventRunner_) {
265 HILOGE("MUST Set event runner before removing events by id and param");
266 return;
267 }
268
269 eventRunner_->GetEventQueue()->Remove(shared_from_this(), innerEventId, param);
270 }
271
RemoveTask(const std::string & name)272 void EventHandler::RemoveTask(const std::string &name)
273 {
274 HILOGD("RemoveTask enter");
275 if (!eventRunner_) {
276 HILOGE("MUST Set event runner before removing events by task name");
277 return;
278 }
279
280 eventRunner_->GetEventQueue()->Remove(shared_from_this(), name);
281 }
282
RemoveTaskWithRet(const std::string & name)283 int EventHandler::RemoveTaskWithRet(const std::string &name)
284 {
285 HILOGD("RemoveTaskWithRet enter");
286 if (!eventRunner_) {
287 HILOGE("MUST Ret Set event runner before removing events by task name");
288 return FFRT_TASK_REMOVE_FAIL;
289 }
290
291 bool ret = eventRunner_->GetEventQueue()->Remove(shared_from_this(), name);
292 return ret ? FFRT_SUCCESS : FFRT_TASK_REMOVE_FAIL;
293 }
294
AddFileDescriptorListener(int32_t fileDescriptor,uint32_t events,const std::shared_ptr<FileDescriptorListener> & listener,const std::string & taskName)295 ErrCode EventHandler::AddFileDescriptorListener(int32_t fileDescriptor, uint32_t events,
296 const std::shared_ptr<FileDescriptorListener> &listener, const std::string &taskName)
297 {
298 return AddFileDescriptorListener(fileDescriptor, events, listener, taskName, EventQueue::Priority::HIGH);
299 }
300
AddFileDescriptorListener(int32_t fileDescriptor,uint32_t events,const std::shared_ptr<FileDescriptorListener> & listener,const std::string & taskName,EventQueue::Priority priority)301 ErrCode EventHandler::AddFileDescriptorListener(int32_t fileDescriptor, uint32_t events,
302 const std::shared_ptr<FileDescriptorListener> &listener, const std::string &taskName,
303 EventQueue::Priority priority)
304 {
305 HILOGD("enter");
306 if ((fileDescriptor < 0) || ((events & FILE_DESCRIPTOR_EVENTS_MASK) == 0) || (!listener)) {
307 HILOGE("%{public}d, %{public}u, %{public}s: Invalid parameter",
308 fileDescriptor, events, listener ? "valid" : "null");
309 return EVENT_HANDLER_ERR_INVALID_PARAM;
310 }
311
312 if (!eventRunner_) {
313 HILOGE("MUST Set event runner before adding fd listener");
314 return EVENT_HANDLER_ERR_NO_EVENT_RUNNER;
315 }
316
317 listener->SetOwner(shared_from_this());
318 return eventRunner_->GetEventQueue()->AddFileDescriptorListener(fileDescriptor, events, listener, taskName,
319 priority);
320 }
321
RemoveAllFileDescriptorListeners()322 void EventHandler::RemoveAllFileDescriptorListeners()
323 {
324 HILOGD("enter");
325 if (!eventRunner_) {
326 HILOGE("MUST Set event runner before removing all fd listener");
327 return;
328 }
329
330 eventRunner_->GetEventQueue()->RemoveFileDescriptorListener(shared_from_this());
331 }
332
RemoveFileDescriptorListener(int32_t fileDescriptor)333 void EventHandler::RemoveFileDescriptorListener(int32_t fileDescriptor)
334 {
335 HILOGD("enter");
336 if (fileDescriptor < 0) {
337 HILOGE("fd %{public}d: Invalid parameter", fileDescriptor);
338 return;
339 }
340
341 if (!eventRunner_) {
342 HILOGE("MUST Set event runner before removing fd listener by fd");
343 return;
344 }
345
346 eventRunner_->GetEventQueue()->RemoveFileDescriptorListener(fileDescriptor);
347 }
348
SetEventRunner(const std::shared_ptr<EventRunner> & runner)349 void EventHandler::SetEventRunner(const std::shared_ptr<EventRunner> &runner)
350 {
351 HILOGD("enter");
352 if (eventRunner_ == runner) {
353 return;
354 }
355
356 if (eventRunner_) {
357 HILOGW("It is not recommended to change the event runner dynamically");
358
359 // Remove all events and listeners from old event runner.
360 RemoveAllEvents();
361 RemoveAllFileDescriptorListeners();
362 }
363
364 // Switch event runner.
365 eventRunner_ = runner;
366 return;
367 }
368
DeliveryTimeAction(const InnerEvent::Pointer & event,InnerEvent::TimePoint nowStart)369 void EventHandler::DeliveryTimeAction(const InnerEvent::Pointer &event, InnerEvent::TimePoint nowStart)
370 {
371 #ifdef HAS_HICHECKER_NATIVE_PART
372 HILOGD("enter");
373 if (!HiChecker::NeedCheckSlowEvent()) {
374 return;
375 }
376 int64_t deliveryTimeout = eventRunner_->GetDeliveryTimeout();
377 if (deliveryTimeout > 0) {
378 std::string threadName = eventRunner_->GetRunnerThreadName();
379 std::string eventName = GetEventName(event);
380 int64_t threadId = getproctid();
381 std::string threadIdCharacter = std::to_string(threadId);
382 std::chrono::duration<double> deliveryTime = nowStart - event->GetSendTime();
383 std::string deliveryTimeCharacter = std::to_string((deliveryTime).count());
384 std::string deliveryTimeoutCharacter = std::to_string(deliveryTimeout);
385 std::string handOutTag = "threadId: " + threadIdCharacter + "," + "threadName: " + threadName + "," +
386 "eventName: " + eventName + "," + "deliveryTime: " + deliveryTimeCharacter + "," +
387 "deliveryTimeout: " + deliveryTimeoutCharacter;
388 if ((nowStart - std::chrono::milliseconds(deliveryTimeout)) > event->GetHandleTime()) {
389 HiChecker::NotifySlowEvent(handOutTag);
390 if (deliveryTimeoutCallback_) {
391 deliveryTimeoutCallback_();
392 }
393 }
394 }
395 #endif // HAS_HICHECKER_NATIVE_PART
396 }
397
DistributeTimeAction(const InnerEvent::Pointer & event,InnerEvent::TimePoint nowStart)398 void EventHandler::DistributeTimeAction(const InnerEvent::Pointer &event, InnerEvent::TimePoint nowStart)
399 {
400 #ifdef HAS_HICHECKER_NATIVE_PART
401 HILOGD("enter");
402 if (!HiChecker::NeedCheckSlowEvent()) {
403 return;
404 }
405 int64_t distributeTimeout = eventRunner_->GetDistributeTimeout();
406 if (distributeTimeout > 0) {
407 std::string threadName = eventRunner_->GetRunnerThreadName();
408 std::string eventName = GetEventName(event);
409 int64_t threadId = getproctid();
410 std::string threadIdCharacter = std::to_string(threadId);
411 InnerEvent::TimePoint nowEnd = InnerEvent::Clock::now();
412 std::chrono::duration<double> distributeTime = nowEnd - nowStart;
413 std::string distributeTimeCharacter = std::to_string((distributeTime).count());
414 std::string distributeTimeoutCharacter = std::to_string(distributeTimeout);
415 std::string executeTag = "threadId: " + threadIdCharacter + "," + "threadName: " + threadName + "," +
416 "eventName: " + eventName + "," + "distributeTime: " + distributeTimeCharacter + "," +
417 "distributeTimeout: " + distributeTimeoutCharacter;
418 if ((nowEnd - std::chrono::milliseconds(distributeTimeout)) > nowStart) {
419 HiChecker::NotifySlowEvent(executeTag);
420 if (distributeTimeoutCallback_) {
421 distributeTimeoutCallback_();
422 }
423 }
424 }
425 #endif // HAS_HICHECKER_NATIVE_PART
426 }
427
DistributeTimeoutHandler(const InnerEvent::TimePoint & beginTime)428 void EventHandler::DistributeTimeoutHandler(const InnerEvent::TimePoint& beginTime)
429 {
430 int64_t distributeTimeout = EventRunner::GetMainEventRunner()->GetTimeout();
431 if (distributeTimeout > 0) {
432 InnerEvent::TimePoint endTime = InnerEvent::Clock::now();
433 if ((endTime - std::chrono::milliseconds(distributeTimeout)) > beginTime &&
434 EventRunner::distributeCallback_) {
435 HILOGI("AppMainThread Callback.");
436 auto diff = endTime - beginTime;
437 int64_t durationTime = std::chrono::duration_cast<std::chrono::milliseconds>(diff).count();
438 EventRunner::distributeCallback_(durationTime);
439 }
440 }
441 }
442
DistributeEvent(const InnerEvent::Pointer & event)443 void EventHandler::DistributeEvent(const InnerEvent::Pointer &event) __attribute__((no_sanitize("cfi")))
444 {
445 if (!event) {
446 HILOGE("Could not distribute an invalid event");
447 return;
448 }
449
450 currentEventHandler = shared_from_this();
451 if (enableEventLog_) {
452 auto now = InnerEvent::Clock::now();
453 auto currentRunningInfo = "start at " + InnerEvent::DumpTimeToString(now) + "; " + event->Dump() +
454 eventRunner_->GetEventQueue()->DumpCurrentQueueSize();
455 HILOGD("%{public}s", currentRunningInfo.c_str());
456 }
457
458 StartTraceAdapter(event);
459
460 auto spanId = event->GetTraceId();
461 auto traceId = HiTraceChain::GetId();
462 bool allowTraceOutPut = AllowHiTraceOutPut(spanId, event->HasWaiter());
463 if (allowTraceOutPut) {
464 HiTraceChain::SetId(*spanId);
465 HiTracePointerOutPut(spanId, event, "Receive", HiTraceTracepointType::HITRACE_TP_SR);
466 }
467
468 InnerEvent::TimePoint nowStart = InnerEvent::Clock::now();
469 DeliveryTimeAction(event, nowStart);
470 HILOGD("EventName is %{public}s, eventId is %{public}s priority %{public}d.", GetEventName(event).c_str(),
471 (event->GetEventUniqueId()).c_str(), event->GetEventPriority());
472
473 std::string eventName = GetEventName(event);
474 InnerEvent::TimePoint beginTime;
475 bool isAppMainThread = EventRunner::IsAppMainThread();
476 if (EventRunner::distributeBegin_ && isAppMainThread) {
477 beginTime = EventRunner::distributeBegin_(eventName);
478 }
479
480 if (event->HasTask()) {
481 // Call task callback directly if contains a task.
482 HILOGD("excute event taskCallback, event address: %{public}p ", &(event->GetTaskCallback()));
483 (event->GetTaskCallback())();
484 } else {
485 // Otherwise let developers to handle it.
486 ProcessEvent(event);
487 }
488
489 if (EventRunner::distributeBegin_ && EventRunner::distributeEnd_ && isAppMainThread) {
490 EventRunner::distributeEnd_(eventName, beginTime);
491 DistributeTimeoutHandler(beginTime);
492 }
493
494 DistributeTimeAction(event, nowStart);
495
496 if (allowTraceOutPut) {
497 HiTraceChain::Tracepoint(HiTraceTracepointType::HITRACE_TP_SS, *spanId, "Event Distribute over");
498 HiTraceChain::ClearId();
499 if (traceId.IsValid()) {
500 HiTraceChain::SetId(traceId);
501 }
502 }
503 if (enableEventLog_) {
504 auto now = InnerEvent::Clock::now();
505 HILOGD("end at %{public}s", InnerEvent::DumpTimeToString(now).c_str());
506 }
507 FinishTraceAdapter();
508 }
509
Dump(Dumper & dumper)510 void EventHandler::Dump(Dumper &dumper)
511 {
512 HILOGI("EventHandler start dumper!");
513 auto now = std::chrono::system_clock::now();
514 dumper.Dump(dumper.GetTag() + " EventHandler dump begin curTime: " +
515 InnerEvent::DumpTimeToString(now) + std::string(LINE_SEPARATOR));
516 if (eventRunner_ == nullptr) {
517 dumper.Dump(dumper.GetTag() + " event runner uninitialized!" + std::string(LINE_SEPARATOR));
518 } else {
519 eventRunner_->Dump(dumper);
520 }
521 }
522
HasInnerEvent(uint32_t innerEventId)523 bool EventHandler::HasInnerEvent(uint32_t innerEventId)
524 {
525 if (!eventRunner_) {
526 HILOGE("event runner uninitialized!");
527 return false;
528 }
529 return eventRunner_->GetEventQueue()->HasInnerEvent(shared_from_this(), innerEventId);
530 }
531
HasInnerEvent(int64_t param)532 bool EventHandler::HasInnerEvent(int64_t param)
533 {
534 if (!eventRunner_) {
535 HILOGE("event runner uninitialized!");
536 return false;
537 }
538 return eventRunner_->GetEventQueue()->HasInnerEvent(shared_from_this(), param);
539 }
540
GetEventName(const InnerEvent::Pointer & event)541 std::string EventHandler::GetEventName(const InnerEvent::Pointer &event)
542 {
543 std::string eventName;
544 if (!event) {
545 HILOGW("event is nullptr");
546 return eventName;
547 }
548
549 if (event->HasTask()) {
550 eventName = event->GetTaskName();
551 } else {
552 InnerEvent::EventId eventId = event->GetInnerEventIdEx();
553 if (eventId.index() == TYPE_U32_INDEX) {
554 eventName = std::to_string(std::get<uint32_t>(eventId));
555 } else {
556 eventName = std::get<std::string>(eventId);
557 }
558 }
559 return eventName;
560 }
561
IsIdle()562 bool EventHandler::IsIdle()
563 {
564 return eventRunner_->GetEventQueue()->IsIdle();
565 }
566
ProcessEvent(const InnerEvent::Pointer &)567 void EventHandler::ProcessEvent(const InnerEvent::Pointer &)
568 {}
569
EnableEventLog(bool enableEventLog)570 void EventHandler::EnableEventLog(bool enableEventLog)
571 {
572 enableEventLog_ = enableEventLog;
573 }
574
HasPreferEvent(int basePrio)575 bool EventHandler::HasPreferEvent(int basePrio)
576 {
577 return eventRunner_->GetEventQueue()->HasPreferEvent(basePrio);
578 }
579
QueryPendingTaskInfo(int32_t fileDescriptor)580 PendingTaskInfo EventHandler::QueryPendingTaskInfo(int32_t fileDescriptor)
581 {
582 if (!eventRunner_) {
583 HILOGE("QueryPendingTaskInfo event runner uninitialized!");
584 return PendingTaskInfo();
585 }
586 return eventRunner_->GetEventQueue()->QueryPendingTaskInfo(fileDescriptor);
587 }
588
TaskCancelAndWait()589 void EventHandler::TaskCancelAndWait()
590 {
591 #ifdef FFRT_USAGE_ENABLE
592 if (!eventRunner_) {
593 HILOGE("CancelAndWait error,event runner is nullptr");
594 return;
595 }
596 if (eventRunner_->threadMode_ == ThreadMode::FFRT) {
597 eventRunner_->GetEventQueue()->CancelAndWait();
598 }
599 #endif
600 }
601
GetMainEventHandlerForFFRT()602 extern "C" void* GetMainEventHandlerForFFRT()
603 {
604 HILOGD("GetMainEventHandlerForFFRT enter");
605 static std::shared_ptr<OHOS::AppExecFwk::EventHandler> mainHandler =
606 std::make_shared<OHOS::AppExecFwk::EventHandler>(OHOS::AppExecFwk::EventRunner::GetMainEventRunner());
607 if (mainHandler == nullptr) {
608 HILOGW("GetMainEventHandlerForFFRT execute fail, mainHandler is nullptr");
609 return nullptr;
610 }
611 return &mainHandler;
612 }
613
GetCurrentEventHandlerForFFRT()614 extern "C" void* GetCurrentEventHandlerForFFRT()
615 {
616 HILOGD("GetCurrentEventHandlerForFFRT enter");
617 thread_local std::shared_ptr<OHOS::AppExecFwk::EventHandler> currentHandler =
618 std::make_shared<OHOS::AppExecFwk::EventHandler>(OHOS::AppExecFwk::EventRunner::Current());
619 if (currentHandler == nullptr) {
620 HILOGW("GetCurrentEventHandlerForFFRT execute fail, currentHandler is nullptr");
621 return nullptr;
622 }
623 return ¤tHandler;
624 }
625
PostTaskByFFRT(void * handler,const std::function<void ()> & callback,const TaskOptions & task)626 extern "C" bool PostTaskByFFRT(void* handler, const std::function<void()>& callback, const TaskOptions &task)
627 {
628 HILOGD("PostTaskByFFRT enter");
629 if (handler == nullptr) {
630 HILOGW("PostTaskByFFRT execute fail, handler is nullptr");
631 return false;
632 }
633 std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
634 Caller caller = {};
635 caller.dfxName_ = task.dfxName_;
636 return (*ptr)->PostTask(callback, std::to_string(task.taskId_), task.delayTime_, task.priority_, caller);
637 }
638
PostSyncTaskByFFRT(void * handler,const std::function<void ()> & callback,const std::string & name,EventQueue::Priority priority)639 extern "C" bool PostSyncTaskByFFRT(void* handler, const std::function<void()>& callback,
640 const std::string &name, EventQueue::Priority priority)
641 {
642 HILOGD("PostSyncTaskByFFRT enter");
643 if (handler == nullptr) {
644 HILOGW("PostSyncTaskByFFRT execute fail, handler is nullptr");
645 return false;
646 }
647 std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
648 return (*ptr)->PostSyncTask(callback, name, priority);
649 }
650
RemoveTaskForFFRT(void * handler,const uintptr_t taskId)651 extern "C" int RemoveTaskForFFRT(void* handler, const uintptr_t taskId)
652 {
653 HILOGD("RemoveTaskForFFRT enter");
654 if (handler == nullptr) {
655 HILOGW("RemoveTaskForFFRT execute fail, handler is nullptr");
656 return FFRT_TASK_REMOVE_FAIL;
657 }
658 std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
659 return (*ptr)->RemoveTaskWithRet(std::to_string(taskId));
660 }
661
RemoveAllTaskForFFRT(void * handler)662 extern "C" void RemoveAllTaskForFFRT(void* handler)
663 {
664 HILOGD("RemoveAllTaskForFFRT enter");
665 if (handler == nullptr) {
666 HILOGW("RemoveAllTaskForFFRT execute fail, handler is nullptr");
667 return;
668 }
669 std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
670 (*ptr)->RemoveAllEvents();
671 }
672
AddFdListenerByFFRT(void * handler,uint32_t fd,uint32_t event,void * data,ffrt_poller_cb cb)673 extern "C" int AddFdListenerByFFRT(void* handler, uint32_t fd, uint32_t event, void* data, ffrt_poller_cb cb)
674 {
675 if (handler == nullptr) {
676 HILOGW("AddFdListenerByFFRT execute fail, handler is nullptr");
677 return FFRT_ERROR;
678 }
679
680 auto listener = std::make_shared<FfrtDescriptorListener>(event, data, cb);
681 std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
682 if ((*ptr) == nullptr) {
683 HILOGW("AddFdListenerByFFRT execute failed");
684 return FFRT_ERROR;
685 }
686 uint32_t innerEvent = FfrtDescriptorListener::ConvertEvents(event);
687 std::string taskName = "FFRT_FD_" + std::to_string(fd);
688 ErrCode result = (*ptr)->AddFileDescriptorListener(fd, innerEvent, listener, taskName);
689 return (result == ERR_OK) ? FFRT_SUCCESS : FFRT_ERROR;
690 }
691
RemoveFdListenerByFFRT(void * handler,uint32_t fd)692 extern "C" int RemoveFdListenerByFFRT(void* handler, uint32_t fd)
693 {
694 if (handler == nullptr) {
695 HILOGW("RemoveFdListenerByFFRT execute fail, handler is nullptr");
696 return FFRT_ERROR;
697 }
698
699 std::shared_ptr<EventHandler>* ptr = reinterpret_cast<std::shared_ptr<EventHandler>*>(handler);
700 if ((*ptr) == nullptr) {
701 HILOGW("RemoveFdListenerByFFRT execute failed");
702 return FFRT_ERROR;
703 }
704 (*ptr)->RemoveFileDescriptorListener(fd);
705 return FFRT_SUCCESS;
706 }
707 } // namespace AppExecFwk
708 } // namespace OHOS
709