1 /*
2  * Copyright (c) 2024 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 #ifndef __FFRT_EVENT_HANDLER_ADAPTER_H__
17 #define __FFRT_EVENT_HANDLER_ADAPTER_H__
18 #include <dlfcn.h>
19 #include <string>
20 #include <mutex>
21 #include "dfx/log/ffrt_log_api.h"
22 #include "c/type_def.h"
23 
24 namespace ffrt {
25 #if (defined(__aarch64__) || defined(__x86_64__))
26 static const std::string EVENTHANDLER_LIB_PATH = "/system/lib64/chipset-pub-sdk/libeventhandler.z.so";
27 #else
28 static const std::string EVENTHANDLER_LIB_PATH = "/system/lib/chipset-pub-sdk/libeventhandler.z.so";
29 #endif
30 
31 enum class Priority : uint32_t {
32     // The highest priority queue, should be distributed until the tasks in the queue are completed.
33     VIP = 0,
34     // Event that should be distributed at once if possible.
35     IMMEDIATE,
36     // High priority event, sorted by handle time, should be distributed before low priority event.
37     HIGH,
38     // Normal event, sorted by handle time.
39     LOW,
40     // Event that should be distributed only if no other event right now.
41     IDLE,
42 };
43 
44 struct TaskOptions {
45     std::string dfxName_;
46     int64_t delayTime_;
47     Priority priority_;
48     uintptr_t taskId_;
TaskOptionsTaskOptions49     TaskOptions(std::string dfxName, int64_t delayTime, Priority priority, uintptr_t taskId)
50         : dfxName_(dfxName), delayTime_(delayTime), priority_(priority), taskId_(taskId) {}
51 };
52 
53 void* GetMainEventHandlerForFFRT();
54 void* GetCurrentEventHandlerForFFRT();
55 bool PostTaskByFFRT(void* handler, const std::function<void()>& callback, const TaskOptions& task);
56 int RemoveTaskForFFRT(void* handler, const uintptr_t taskId);
57 int AddFdListenerByFFRT(void* handler, uint32_t fd, uint32_t event, void* data, ffrt_poller_cb cb);
58 int RemoveFdListenerByFFRT(void* handler, uint32_t fd);
59 
60 using GetMainEventHandlerType = decltype(GetMainEventHandlerForFFRT)*;
61 using GetCurrentEventHandlerType = decltype(GetCurrentEventHandlerForFFRT)*;
62 using PostTaskType = decltype(PostTaskByFFRT)*;
63 using RemoveTaskType = decltype(RemoveTaskForFFRT)*;
64 using AddFdListenerType = decltype(AddFdListenerByFFRT)*;
65 using RemoveFdListenerType = decltype(RemoveFdListenerByFFRT)*;
66 
67 class EventHandlerAdapter {
68 public:
EventHandlerAdapter()69     EventHandlerAdapter()
70     {
71         std::lock_guard<std::mutex> guard(mutex_);
72         Load();
73     }
74 
~EventHandlerAdapter()75     ~EventHandlerAdapter()
76     {
77     }
78 
Instance()79     static EventHandlerAdapter* Instance()
80     {
81         static EventHandlerAdapter instance;
82         return &instance;
83     }
84 
ConvertPriority(ffrt_queue_priority_t priority)85     Priority ConvertPriority(ffrt_queue_priority_t priority)
86     {
87         return static_cast<Priority>(priority + 1);
88     }
89 
90     GetMainEventHandlerType GetMainEventHandler = nullptr;
91     GetCurrentEventHandlerType GetCurrentEventHandler = nullptr;
92     PostTaskType PostTask = nullptr;
93     RemoveTaskType RemoveTask = nullptr;
94     AddFdListenerType AddFdListener = nullptr;
95     RemoveFdListenerType RemoveFdListener = nullptr;
96 
97 private:
Load()98     void Load()
99     {
100         if (handle_ != nullptr) {
101             return;
102         }
103 
104         handle_ = dlopen(EVENTHANDLER_LIB_PATH.c_str(), RTLD_NOW | RTLD_LOCAL);
105         if (handle_ == nullptr) {
106             FFRT_LOGE("eventhandler lib handle is null.");
107             return;
108         }
109 
110         GetMainEventHandler = reinterpret_cast<GetMainEventHandlerType>(
111             dlsym(handle_, "GetMainEventHandlerForFFRT"));
112         if (GetMainEventHandler == nullptr) {
113             FFRT_LOGE("get GetMainEventHandlerForFFRT symbol fail.");
114             return;
115         }
116 
117         GetCurrentEventHandler = reinterpret_cast<GetCurrentEventHandlerType>(
118             dlsym(handle_, "GetCurrentEventHandlerForFFRT"));
119         if (GetCurrentEventHandler == nullptr) {
120             FFRT_LOGE("get GetCurrentEventHandlerForFFRT symbol fail.");
121             return;
122         }
123 
124         PostTask = reinterpret_cast<PostTaskType>(
125             dlsym(handle_, "PostTaskByFFRT"));
126         if (PostTask == nullptr) {
127             FFRT_LOGE("get PostTaskByFFRT symbol fail.");
128             return;
129         }
130 
131         RemoveTask = reinterpret_cast<RemoveTaskType>(
132             dlsym(handle_, "RemoveTaskForFFRT"));
133         if (RemoveTask == nullptr) {
134             FFRT_LOGE("get RemoveTaskForFFRT symbol fail.");
135             return;
136         }
137 
138         AddFdListener = reinterpret_cast<AddFdListenerType>(
139             dlsym(handle_, "AddFdListenerByFFRT"));
140         if (AddFdListener == nullptr) {
141             FFRT_LOGE("get AddFdListenerByFFRT symbol fail.");
142             return;
143         }
144 
145         RemoveFdListener = reinterpret_cast<RemoveFdListenerType>(
146             dlsym(handle_, "RemoveFdListenerByFFRT"));
147         if (RemoveFdListener == nullptr) {
148             FFRT_LOGE("get RemoveFdListenerByFFRT symbol fail.");
149             return;
150         }
151     }
152 
153     void* handle_ = nullptr;
154     std::mutex mutex_;
155 };
156 }  // namespace ffrt
157 #endif // __FFRT_EVENT_HANDLER_ADAPTER_H__