mirror of
https://gitee.com/openharmony/bundlemanager_bundle_framework
synced 2025-02-17 06:28:19 +00:00
!7455 fix napi_ref null
Merge pull request !7455 from zhrenqiang/napiref
This commit is contained in:
commit
6bcd0b4c6f
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user