1 /*
2 * Copyright (c) 2022-2025 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 "stub_collector.h"
17 #include <hdf_core_log.h>
18 #include <map>
19 #include <mutex>
20 #include "hdi_mutex.h"
21
22 static std::map<std::string, StubConstructor *> g_constructorMap;
23 static std::map<void *, HdfRemoteService **> g_stubMap;
24 static mutex_t g_consMapLock;
25 static mutex_t g_stubMapLock;
26
StubConstructorRegister(const char * ifDesc,struct StubConstructor * constructor)27 void StubConstructorRegister(const char *ifDesc, struct StubConstructor *constructor)
28 {
29 if (ifDesc == nullptr || constructor == nullptr) {
30 return;
31 }
32
33 const std::lock_guard<mutex_t> lock(g_consMapLock);
34 if (g_constructorMap.find(ifDesc) != g_constructorMap.end()) {
35 HDF_LOGE("repeat registration stub constructor for if %{public}s", ifDesc);
36 return;
37 }
38 g_constructorMap.emplace(std::make_pair(ifDesc, constructor));
39 return;
40 }
41
StubConstructorUnregister(const char * ifDesc,const struct StubConstructor * constructor)42 void StubConstructorUnregister(const char *ifDesc, const struct StubConstructor *constructor)
43 {
44 if (ifDesc == nullptr || constructor == nullptr) {
45 return;
46 }
47
48 const std::lock_guard<mutex_t> lock(g_consMapLock);
49 g_constructorMap.erase(ifDesc);
50 return;
51 }
52
StubCollectorGetOrNewObject(const char * ifDesc,void * servPtr)53 struct HdfRemoteService **StubCollectorGetOrNewObject(const char *ifDesc, void *servPtr)
54 {
55 if (ifDesc == nullptr || servPtr == nullptr) {
56 return nullptr;
57 }
58 const std::lock_guard<mutex_t> stublock(g_stubMapLock);
59 auto stub = g_stubMap.find(servPtr);
60 if (stub != g_stubMap.end()) {
61 return stub->second;
62 }
63
64 HDF_LOGI("g_constructorMap size %{public}zu", g_constructorMap.size());
65 const std::lock_guard<mutex_t> lock(g_consMapLock);
66 for (auto &consruct : g_constructorMap) {
67 HDF_LOGI("g_constructorMap it: %{public}s", consruct.first.c_str());
68 }
69
70 auto constructor = g_constructorMap.find(ifDesc);
71 if (constructor == g_constructorMap.end()) {
72 HDF_LOGE("no stub constructor for %{public}s", ifDesc);
73 return nullptr;
74 }
75
76 if (constructor->second->constructor == nullptr) {
77 HDF_LOGE("no stub constructor method for %{public}s", ifDesc);
78 return nullptr;
79 }
80
81 HdfRemoteService **stubObject = constructor->second->constructor(servPtr);
82 if (stubObject == nullptr) {
83 HDF_LOGE("failed to construct stub obj %{public}s", ifDesc);
84 return nullptr;
85 }
86 g_stubMap.insert(std::make_pair(servPtr, stubObject));
87 return stubObject;
88 }
89
StubCollectorRemoveObject(const char * ifDesc,void * servPtr)90 void StubCollectorRemoveObject(const char *ifDesc, void *servPtr)
91 {
92 if (ifDesc == nullptr || servPtr == nullptr) {
93 return;
94 }
95
96 const std::lock_guard<mutex_t> stublock(g_stubMapLock);
97 auto stub = g_stubMap.find(servPtr);
98 if (stub == g_stubMap.end()) {
99 return;
100 }
101 const std::lock_guard<mutex_t> lock(g_consMapLock);
102 auto constructor = g_constructorMap.find(ifDesc);
103 if (constructor == g_constructorMap.end()) {
104 HDF_LOGE("no stub constructor for %{public}s", ifDesc);
105 return;
106 }
107
108 if (constructor->second->destructor != nullptr) {
109 constructor->second->destructor(stub->second);
110 }
111
112 g_stubMap.erase(servPtr);
113 }
114