• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "bindable_sub_thread.h"
17 
18 #include "hilog_tag_wrapper.h"
19 #include "native_engine/native_engine.h"
20 
21 namespace OHOS {
22 namespace AbilityRuntime {
23 namespace {
24 struct HookData {
25     std::weak_ptr<BindableSubThread> instance;
26     napi_env env = nullptr;
27 };
28 } // namespace
29 
~BindableSubThread()30 BindableSubThread::~BindableSubThread()
31 {
32     TAG_LOGD(AAFwkTag::CONTEXT, "destructor");
33 }
34 
BindSubThreadObject(void * napiEnv,void * object)35 void BindableSubThread::BindSubThreadObject(void* napiEnv, void* object)
36 {
37     TAG_LOGD(AAFwkTag::CONTEXT, "bind sub thread object");
38     uintptr_t key = reinterpret_cast<uintptr_t>(napiEnv);
39     std::lock_guard guard(objectsMutex_);
40     auto it = objects_.find(key);
41     if (it != objects_.end()) {
42         TAG_LOGD(AAFwkTag::CONTEXT, "object has bound");
43         return;
44     }
45 
46     napi_env acutalEnv = static_cast<napi_env>(napiEnv);
47     HookData* data = new (std::nothrow) HookData { weak_from_this(), acutalEnv };
48     if (data == nullptr) {
49         TAG_LOGE(AAFwkTag::CONTEXT, "data err");
50         return;
51     }
52 
53     napi_status ret = napi_add_env_cleanup_hook(acutalEnv,
54         StaticRemoveSubThreadObject, data);
55     if (ret != napi_status::napi_ok) {
56         TAG_LOGE(AAFwkTag::CONTEXT, "add hook err");
57         delete data;
58         return;
59     }
60 
61     std::unique_ptr<void, void (*)(void*)> obj(object,
62         [](void* ptr) {
63             TAG_LOGD(AAFwkTag::CONTEXT, "delete sub thread ptr");
64             delete static_cast<NativeReference*>(ptr);
65         });
66     objects_.emplace(key, std::move(obj));
67 }
68 
GetSubThreadObject(void * napiEnv)69 void* BindableSubThread::GetSubThreadObject(void* napiEnv)
70 {
71     TAG_LOGD(AAFwkTag::CONTEXT, "get sub thread object");
72     uintptr_t key = reinterpret_cast<uintptr_t>(napiEnv);
73     std::lock_guard guard(objectsMutex_);
74     const auto& iter = objects_.find(key);
75     if (iter == objects_.end()) {
76         TAG_LOGD(AAFwkTag::CONTEXT, "not found target object");
77         return nullptr;
78     }
79     return static_cast<void*>(iter->second.get());
80 }
81 
RemoveSubThreadObject(void * napiEnv)82 void BindableSubThread::RemoveSubThreadObject(void* napiEnv)
83 {
84     TAG_LOGD(AAFwkTag::CONTEXT, "remove sub thread object");
85     uintptr_t key = reinterpret_cast<uintptr_t>(napiEnv);
86     std::lock_guard guard(objectsMutex_);
87     const auto& iter = objects_.find(key);
88     if (iter == objects_.end()) {
89         TAG_LOGW(AAFwkTag::CONTEXT, "not found target object");
90         return;
91     }
92     objects_.erase(key);
93 }
94 
RemoveAllObject()95 void BindableSubThread::RemoveAllObject()
96 {
97     TAG_LOGD(AAFwkTag::CONTEXT, "remove all object");
98     std::lock_guard guard(objectsMutex_);
99     objects_.clear();
100 }
101 
StaticRemoveSubThreadObject(void * arg)102 void BindableSubThread::StaticRemoveSubThreadObject(void* arg)
103 {
104     TAG_LOGD(AAFwkTag::CONTEXT, "remove sub thread object");
105     HookData* data = static_cast<HookData*>(arg);
106     if (data == nullptr) {
107         return;
108     }
109 
110     std::shared_ptr<BindableSubThread> instance = data->instance.lock();
111     if (instance == nullptr) {
112         TAG_LOGW(AAFwkTag::CONTEXT, "instance nullptr");
113         delete data;
114         return;
115     }
116 
117     instance->RemoveSubThreadObject(data->env);
118     delete data;
119 }
120 } // namespace AbilityRuntime
121 } // namespace OHOS
122