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