!1209 添加napi_ref的计数逻辑

Merge pull request !1209 from CheerfulRicky/work
This commit is contained in:
openharmony_ci 2024-12-20 07:29:58 +00:00 committed by Gitee
commit 283fd74fce
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 70 additions and 8 deletions

View File

@ -29,6 +29,29 @@ static const int32_t GETSUBSCREBEINFO_MAX_PARA = 1;
static const int32_t ARGS_TWO_EVENT = 2;
static const int32_t PARAM0_EVENT = 0;
static const int32_t PARAM1_EVENT = 1;
static const uint32_t NAPI_REF_INITIAL_REF_COUNT = 1;
}
static void NapiIncreaseRef(napi_env env, const napi_ref &ref)
{
if (ref == nullptr) {
return;
}
uint32_t *refCount = new uint32_t;
napi_reference_ref(env, ref, refCount);
}
static void NapiReleaseRef(napi_env env, const napi_ref &ref)
{
if (ref == nullptr) {
return;
}
uint32_t *refCount = new uint32_t;
napi_reference_unref(env, ref, refCount);
if (*refCount == NAPI_REF_INITIAL_REF_COUNT) {
EVENT_LOGD("delete ref");
napi_delete_reference(env, ref);
}
}
std::atomic_ullong SubscriberInstance::subscriberID_ = 0;
@ -123,6 +146,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
if (commonEventDataWorkerData->ref == nullptr ||
(commonEventDataWorkerData->valid == nullptr) || *(commonEventDataWorkerData->valid) == false) {
EVENT_LOGE("OnReceiveEvent commonEventDataWorkerData ref is null or invalid which may be previously released");
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
delete commonEventDataWorkerData;
commonEventDataWorkerData = nullptr;
return;
@ -131,6 +155,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
napi_open_handle_scope(commonEventDataWorkerData->env, &scope);
if (scope == nullptr) {
EVENT_LOGE("Scope is null");
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
return;
}
@ -139,6 +164,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
if (SetCommonEventData(commonEventDataWorkerData, result) == nullptr) {
EVENT_LOGE("failed to set common event data");
napi_close_handle_scope(commonEventDataWorkerData->env, scope);
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
delete commonEventDataWorkerData;
commonEventDataWorkerData = nullptr;
return;
@ -158,6 +184,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
commonEventDataWorkerData->env, undefined, callback, ARGS_TWO_EVENT, &results[PARAM0_EVENT], &resultout);
napi_close_handle_scope(commonEventDataWorkerData->env, scope);
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
delete commonEventDataWorkerData;
commonEventDataWorkerData = nullptr;
}
@ -215,6 +242,11 @@ void SubscriberInstance::ClearEnv()
void SubscriberInstance::SetCallbackRef(const napi_ref &ref)
{
EVENT_LOGD("enter");
if (ref != nullptr) {
NapiIncreaseRef(env_, ref);
} else {
NapiReleaseRef(env_, ref_);
}
ref_ = ref;
*valid_ = ref_ != nullptr ? true : false;
}
@ -258,6 +290,7 @@ void SubscriberInstance::OnReceiveEvent(const CommonEventData &data)
commonEventDataWorker->valid = valid_;
std::lock_guard<std::mutex> lock(refMutex_);
commonEventDataWorker->ref = ref_;
NapiIncreaseRef(env_, ref_);
napi_acquire_threadsafe_function(tsfn_);
napi_call_threadsafe_function(tsfn_, commonEventDataWorker, napi_tsfn_nonblocking);
napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
@ -1085,9 +1118,6 @@ void NapiDeleteSubscribe(const napi_env &env, std::shared_ptr<SubscriberInstance
if (subscribe != subscriberInstances.end()) {
std::lock_guard<std::mutex> lock(subscriber->GetRefMutex());
for (auto asyncCallbackInfoSubscribe : subscribe->second.asyncCallbackInfo) {
if (asyncCallbackInfoSubscribe->callback != nullptr) {
napi_delete_reference(env, asyncCallbackInfoSubscribe->callback);
}
delete asyncCallbackInfoSubscribe;
asyncCallbackInfoSubscribe = nullptr;
}

View File

@ -41,6 +41,7 @@ static const int32_t GET_ABORT_MAX_PARA = 1;
static const int32_t FINISH_MAX_PARA = 1;
static const int32_t SUBSCRIBE_EVENT_MAX_NUM = 512;
static const int32_t COMMON_EVENT_PUBLISH_PARAM = 2;
static const uint32_t NAPI_REF_INITIAL_REF_COUNT = 1;
napi_value NapiGetNull(napi_env env)
{
@ -594,7 +595,7 @@ napi_value ParseParametersBySubscribe(const napi_env &env, const napi_value (&ar
EVENT_LOGE("Wrong argument type. Function expected.");
return nullptr;
}
napi_create_reference(env, argv[1], 1, &callback);
napi_create_reference(env, argv[1], NAPI_REF_INITIAL_REF_COUNT, &callback);
return NapiGetNull(env);
}

View File

@ -54,6 +54,7 @@ static const int32_t GET_ABORT_MAX_PARA = 1;
static const int32_t FINISH_MAX_PARA = 1;
static const int32_t PUBLISH_MAX_PARA_AS_USER = 3;
static const int32_t ARGS_DATA_TWO = 2;
static const uint32_t NAPI_REF_INITIAL_REF_COUNT = 1;
void NapiThrow(napi_env env, int32_t errCode)
{
@ -729,7 +730,7 @@ napi_value ParseParametersBySubscribe(const napi_env &env, const napi_value (&ar
NapiThrow(env, ERR_NOTIFICATION_CES_COMMON_PARAM_INVALID, msg);
return nullptr;
}
napi_create_reference(env, argv[1], 1, &callback);
napi_create_reference(env, argv[1], NAPI_REF_INITIAL_REF_COUNT, &callback);
return NapiGetNull(env);
}

View File

@ -37,6 +37,29 @@ static const uint32_t ARGC_ONE = 1;
static const uint32_t ARGC_TWO = 2;
static const int32_t PUBLISH_MAX_PARA_AS_USER = 3;
static const int32_t STR_DATA_MAX_SIZE = 64 * 1024; // 64KB
static const uint32_t NAPI_REF_INITIAL_REF_COUNT = 1;
static void NapiIncreaseRef(napi_env env, const napi_ref &ref)
{
if (ref == nullptr) {
return;
}
uint32_t *refCount = new uint32_t;
napi_reference_ref(env, ref, refCount);
}
static void NapiReleaseRef(napi_env env, const napi_ref &ref)
{
if (ref == nullptr) {
return;
}
uint32_t *refCount = new uint32_t;
napi_reference_unref(env, ref, refCount);
if (*refCount == NAPI_REF_INITIAL_REF_COUNT) {
EVENT_LOGD("delete ref");
napi_delete_reference(env, ref);
}
}
std::atomic_ullong SubscriberInstance::subscriberID_ = 0;
@ -150,6 +173,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
if (commonEventDataWorkerData->ref == nullptr ||
(commonEventDataWorkerData->valid == nullptr) || *(commonEventDataWorkerData->valid) == false) {
EVENT_LOGE("OnReceiveEvent commonEventDataWorkerData ref is null or invalid which may be previously released");
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
delete commonEventDataWorkerData;
commonEventDataWorkerData = nullptr;
return;
@ -158,6 +182,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
napi_open_handle_scope(commonEventDataWorkerData->env, &scope);
if (scope == nullptr) {
EVENT_LOGE("Scope is null");
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
return;
}
@ -165,6 +190,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
napi_create_object(commonEventDataWorkerData->env, &result);
if (SetCommonEventData(commonEventDataWorkerData, result) == nullptr) {
napi_close_handle_scope(commonEventDataWorkerData->env, scope);
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
delete commonEventDataWorkerData;
commonEventDataWorkerData = nullptr;
return;
@ -184,6 +210,7 @@ void ThreadSafeCallback(napi_env env, napi_value jsCallback, void* context, void
commonEventDataWorkerData->env, undefined, callback, ARGS_TWO_EVENT, &results[INDEX_ZERO], &resultout);
napi_close_handle_scope(commonEventDataWorkerData->env, scope);
NapiReleaseRef(commonEventDataWorkerData->env, commonEventDataWorkerData->ref);
delete commonEventDataWorkerData;
commonEventDataWorkerData = nullptr;
}
@ -233,6 +260,11 @@ void SubscriberInstance::ClearEnv()
void SubscriberInstance::SetCallbackRef(const napi_ref &ref)
{
if (ref != nullptr) {
NapiIncreaseRef(env_, ref);
} else {
NapiReleaseRef(env_, ref_);
}
ref_ = ref;
*valid_ = ref_ != nullptr ? true : false;
}
@ -276,6 +308,7 @@ void SubscriberInstance::OnReceiveEvent(const CommonEventData &data)
{
std::lock_guard<std::mutex> lock(refMutex_);
commonEventDataWorker->ref = ref_;
NapiIncreaseRef(env_, ref_);
napi_call_threadsafe_function(tsfn_, commonEventDataWorker, napi_tsfn_nonblocking);
}
napi_release_threadsafe_function(tsfn_, napi_tsfn_release);
@ -714,9 +747,6 @@ void NapiDeleteSubscribe(const napi_env &env, std::shared_ptr<SubscriberInstance
if (subscribe != subscriberInstances.end()) {
std::lock_guard<std::mutex> lock(subscriber->GetRefMutex());
for (auto asyncCallbackInfoSubscribe : subscribe->second.asyncCallbackInfo) {
if (asyncCallbackInfoSubscribe->callback != nullptr) {
napi_delete_reference(env, asyncCallbackInfoSubscribe->callback);
}
delete asyncCallbackInfoSubscribe;
asyncCallbackInfoSubscribe = nullptr;
EVENT_LOGD("asyncCallbackInfoSubscribe is null");