!7455 fix napi_ref null

Merge pull request !7455 from zhrenqiang/napiref
This commit is contained in:
openharmony_ci 2024-11-15 04:11:30 +00:00 committed by Gitee
commit 6bcd0b4c6f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 55 additions and 56 deletions

View File

@ -23,25 +23,56 @@
namespace OHOS {
namespace AppExecFwk {
namespace {
constexpr const char* RESOURCE_NAME = "bmsMonitor";
};
void HandleEnvCleanup(void *data)
{
APP_LOGI("env clean");
if (data != nullptr) {
EventListener *evtListener = static_cast<EventListener *>(data);
evtListener->SetValid(false);
}
}
void JsCallback(napi_env env, napi_value jsCb, void *context, void *data)
{
APP_LOGD("JsCallback");
AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
return;
}
std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env, &scope);
if (scope == nullptr) {
return;
}
napi_value result[ARGS_SIZE_ONE] = { 0 };
napi_value placeHolder = nullptr;
CHKRV_SCOPE(env, napi_create_object(env, &result[ARGS_POS_ZERO]), scope);
CommonFunc::ConvertBundleChangeInfo(env, asyncCallbackInfo->bundleName,
asyncCallbackInfo->userId, asyncCallbackInfo->appIndex, result[0]);
napi_status status = napi_call_function(env, nullptr,
jsCb, sizeof(result) / sizeof(result[0]), result, &placeHolder);
if (status != napi_ok) {
APP_LOGE("napi call %{public}d", status);
}
napi_close_handle_scope(env, scope);
APP_LOGD("JsCallback OK");
}
EventListener::EventListener(napi_env env, const std::string& type) : env_(env), type_(type)
{
napi_status status = napi_add_env_cleanup_hook(env_, HandleEnvCleanup, this);
APP_LOGD("EventListener() %{public}d", status);
APP_LOGI("EventListener() %{public}d", status);
}
EventListener::~EventListener()
{
napi_status status = napi_remove_env_cleanup_hook(env_, HandleEnvCleanup, this);
APP_LOGD("~EventListener() %{public}d", status);
APP_LOGI("~EventListener() %{public}d", status);
}
void EventListener::Add(napi_env env, napi_value handler)
@ -51,8 +82,14 @@ void EventListener::Add(napi_env env, napi_value handler)
return;
}
napi_ref callbackRef = nullptr;
napi_create_reference(env_, handler, 1, &callbackRef);
callbackRefs_.push_back(callbackRef);
NAPI_CALL_RETURN_VOID(env, napi_create_reference(env_, handler, 1, &callbackRef));
napi_threadsafe_function tsfn = nullptr;
napi_value resName = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, RESOURCE_NAME, NAPI_AUTO_LENGTH, &resName));
NAPI_CALL_RETURN_VOID(env, napi_create_threadsafe_function(env, handler,
nullptr, resName, 0, 1, nullptr, nullptr, nullptr, JsCallback, &tsfn));
callbackRefs_.push_back(std::make_pair(callbackRef, tsfn));
}
void EventListener::Delete(napi_env env, napi_value handler)
@ -63,11 +100,12 @@ void EventListener::Delete(napi_env env, napi_value handler)
}
for (auto it = callbackRefs_.begin(); it != callbackRefs_.end();) {
napi_value callback = nullptr;
napi_get_reference_value(env_, *it, &callback);
napi_get_reference_value(env_, (*it).first, &callback);
bool isEquals = false;
napi_strict_equals(env_, handler, callback, &isEquals);
if (isEquals) {
napi_delete_reference(env_, *it);
napi_delete_reference(env_, (*it).first);
napi_release_threadsafe_function((*it).second, napi_threadsafe_function_release_mode::napi_tsfn_release);
it = callbackRefs_.erase(it);
} else {
++it;
@ -84,7 +122,7 @@ bool EventListener::Find(napi_value handler)
{
for (const auto &callbackRef : callbackRefs_) {
napi_value callback = nullptr;
napi_get_reference_value(env_, callbackRef, &callback);
napi_get_reference_value(env_, callbackRef.first, &callback);
bool isEquals = false;
napi_strict_equals(env_, handler, callback, &isEquals);
if (isEquals) {
@ -109,58 +147,20 @@ void EventListener::Emit(std::string &bundleName, int32_t userId, int32_t appInd
}
}
void EventListener::EmitOnUV(const std::string &bundleName, int32_t userId, int32_t appIndex, napi_ref callbackRef)
void EventListener::EmitOnUV(const std::string &bundleName, int32_t userId, int32_t appIndex,
std::pair<napi_ref, napi_threadsafe_function> callbackRef)
{
uv_loop_s* loop = nullptr;
napi_get_uv_event_loop(env_, &loop);
uv_work_t* work = new (std::nothrow) uv_work_t;
if (work == nullptr) {
return;
}
NAPI_CALL_RETURN_VOID(env_, napi_acquire_threadsafe_function(callbackRef.second));
AsyncCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo {
.env = env_,
.bundleName = bundleName,
.userId = userId,
.appIndex = appIndex,
.callbackRef = callbackRef,
};
if (asyncCallbackInfo == nullptr) {
delete work;
return;
}
work->data = reinterpret_cast<void*>(asyncCallbackInfo);
int ret = uv_queue_work(
loop, work, [](uv_work_t* work) { APP_LOGI("EmitOnUV asyn work done"); },
[](uv_work_t* work, int status) {
AsyncCallbackInfo* asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(work->data);
if (asyncCallbackInfo == nullptr) {
return;
}
std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
napi_handle_scope scope = nullptr;
napi_open_handle_scope(asyncCallbackInfo->env, &scope);
if (scope == nullptr) {
return;
}
napi_value callback = nullptr;
napi_value result[ARGS_SIZE_ONE] = { 0 };
napi_value placeHolder = nullptr;
napi_get_reference_value(asyncCallbackInfo->env, asyncCallbackInfo->callbackRef, &callback);
CHKRV_SCOPE(asyncCallbackInfo->env, napi_create_object(asyncCallbackInfo->env,
&result[ARGS_POS_ZERO]), scope);
CommonFunc::ConvertBundleChangeInfo(asyncCallbackInfo->env, asyncCallbackInfo->bundleName,
asyncCallbackInfo->userId, asyncCallbackInfo->appIndex, result[0]);
napi_call_function(asyncCallbackInfo->env, nullptr,
callback, sizeof(result) / sizeof(result[0]), result, &placeHolder);
napi_close_handle_scope(asyncCallbackInfo->env, scope);
if (work != nullptr) {
delete work;
work = nullptr;
}
});
if (ret != 0) {
napi_status status = napi_call_threadsafe_function(callbackRef.second, asyncCallbackInfo,
napi_threadsafe_function_call_mode::napi_tsfn_nonblocking);
if (status != napi_ok) {
APP_LOGE("napi call safe %{public}d", status);
delete asyncCallbackInfo;
delete work;
}
}

View File

@ -37,21 +37,20 @@ public:
void SetValid(bool valid);
private:
bool Find(napi_value handler);
void EmitOnUV(const std::string &bundleName, int32_t userId, int32_t appIndex, napi_ref callbackRef);
void EmitOnUV(const std::string &bundleName, int32_t userId, int32_t appIndex,
std::pair<napi_ref, napi_threadsafe_function> callbackRef);
private:
napi_env env_;
std::string type_;
std::list<napi_ref> callbackRefs_;
std::list<std::pair<napi_ref, napi_threadsafe_function>> callbackRefs_;
bool valid_ = true;
std::mutex validMutex_;
};
struct AsyncCallbackInfo {
napi_env env;
std::string bundleName;
int32_t userId;
int32_t appIndex;
napi_ref callbackRef;
};
}
}