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 &currentHandler;
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