From f0f96ce33890cbc3897495adc4699baaae566b43 Mon Sep 17 00:00:00 2001 From: xusen Date: Wed, 12 Mar 2025 15:30:10 +0800 Subject: [PATCH] Backward group function serialization Backward group function serialization Issue: https://gitee.com/openharmony/commonlibrary_ets_utils/issues/IBSSWA Signed-off-by: xusen --- js_concurrent_module/taskpool/task.cpp | 62 ++++++++++++++++---- js_concurrent_module/taskpool/task.h | 4 ++ js_concurrent_module/taskpool/task_group.cpp | 9 +-- js_concurrent_module/taskpool/taskpool.cpp | 10 +--- 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/js_concurrent_module/taskpool/task.cpp b/js_concurrent_module/taskpool/task.cpp index c54d1d1d..50d0be49 100644 --- a/js_concurrent_module/taskpool/task.cpp +++ b/js_concurrent_module/taskpool/task.cpp @@ -252,6 +252,36 @@ Task* Task::GenerateFunctionTask(napi_env env, napi_value func, napi_value* args return task; } +Task* Task::GenerateGroupFunctionTask(napi_env env, napi_value func, napi_value *args, + size_t argc, TaskType type, napi_value napiTask) +{ + HILOG_DEBUG("taskpool:: task GenerateGroupFunctionTask"); + napi_value argsArray; + napi_create_array_with_length(env, argc, &argsArray); + for (size_t i = 0; i < argc; i++) { + napi_set_element(env, argsArray, i, args[i]); + } + void* serializationFunction = SerializationFunction(env, func); + if (serializationFunction == nullptr) { + HILOG_ERROR("taskpool:: GenerateGroupFunctionTask end, failed to serialize function."); + return nullptr; + } + // only check function is valid when serialization is successful + napi_delete_serialization_data(env, serializationFunction); + napi_value napiFuncName = NapiHelper::GetNameProperty(env, func, NAME); + char* nameStr = NapiHelper::GetChars(env, napiFuncName); + Task* task = new Task(env, type, nameStr); + delete[] nameStr; + task->InitHandle(env); + if (!task->IsMainThreadTask()) { + napi_add_env_cleanup_hook(env, CleanupHookFunc, task); + } + TaskManager::GetInstance().StoreTask(task); + napi_set_named_property(env, napiTask, FUNCTION_STR, func); + napi_set_named_property(env, napiTask, ARGUMENTS_STR, argsArray); + return task; +} + napi_value Task::GetTaskInfoPromise(napi_env env, napi_value task, TaskType taskType, Priority priority) { TaskInfo* taskInfo = GetTaskInfo(env, task, priority); @@ -1068,20 +1098,14 @@ TaskInfo* Task::GenerateTaskInfo(napi_env env, napi_value func, napi_value args, bool defaultTransfer, bool defaultCloneSendable) { HILOG_DEBUG("taskpool:: task GenerateTaskInfo"); - napi_value undefined = NapiHelper::GetUndefinedValue(env); - void* serializationFunction = nullptr; - napi_status status = napi_serialize_inner(env, func, undefined, undefined, - defaultTransfer, defaultCloneSendable, &serializationFunction); - std::string errMessage = ""; - if (status != napi_ok || serializationFunction == nullptr) { - errMessage = "taskpool: failed to serialize function."; - HILOG_ERROR("%{public}s", errMessage.c_str()); - ErrorHelper::ThrowError(env, ErrorHelper::ERR_NOT_CONCURRENT_FUNCTION, errMessage.c_str()); + void* serializationFunction = SerializationFunction(env, func); + if (serializationFunction == nullptr) { return nullptr; } + std::string errMessage = ""; void* serializationArguments = nullptr; - status = napi_serialize_inner(env, args, transferList, cloneList, - defaultTransfer, defaultCloneSendable, &serializationArguments); + napi_status status = napi_serialize_inner(env, args, transferList, cloneList, + defaultTransfer, defaultCloneSendable, &serializationArguments); if (status != napi_ok || serializationArguments == nullptr) { errMessage = "taskpool: failed to serialize arguments."; HILOG_ERROR("%{public}s", errMessage.c_str()); @@ -1844,4 +1868,20 @@ uint32_t Task::GetTaskId() const { return taskId_; } + +void* Task::SerializationFunction(napi_env env, napi_value func, bool defaultTransfer, bool defaultCloneSendable) +{ + napi_value undefined = NapiHelper::GetUndefinedValue(env); + void *result = nullptr; + napi_status status = napi_serialize_inner(env, func, undefined, undefined, + defaultTransfer, defaultCloneSendable, &result); + std::string errMessage = ""; + if (status != napi_ok || result == nullptr) { + errMessage = "taskpool: failed to serialize function."; + HILOG_ERROR("%{public}s", errMessage.c_str()); + ErrorHelper::ThrowError(env, ErrorHelper::ERR_NOT_CONCURRENT_FUNCTION, errMessage.c_str()); + return nullptr; + } + return result; +} } // namespace Commonlibrary::Concurrent::TaskPoolModule \ No newline at end of file diff --git a/js_concurrent_module/taskpool/task.h b/js_concurrent_module/taskpool/task.h index 5d460db6..42d902b3 100644 --- a/js_concurrent_module/taskpool/task.h +++ b/js_concurrent_module/taskpool/task.h @@ -125,6 +125,8 @@ public: static Task* GenerateTask(napi_env env, napi_value task, napi_value func, napi_value name, napi_value* args, size_t argc); static Task* GenerateFunctionTask(napi_env env, napi_value func, napi_value* args, size_t argc, TaskType type); + static Task* GenerateGroupFunctionTask(napi_env env, napi_value func, napi_value* args, + size_t argc, TaskType type, napi_value napiTask); static TaskInfo* GenerateTaskInfo(napi_env env, napi_value func, napi_value args, napi_value transferList, napi_value cloneList, Priority priority, bool defaultTransfer = true, bool defaultCloneSendable = false); @@ -137,6 +139,8 @@ public: static void CleanupHookFunc(void* arg); static void Cancel(const uv_async_t* req); static void DiscardTask(const uv_async_t* req); + static void* SerializationFunction(napi_env env, napi_value func, + bool defaultTransfer = true, bool defaultCloneSendable = false); void StoreTaskId(uint32_t taskId); napi_value GetTaskInfoPromise(napi_env env, napi_value task, TaskType taskType = TaskType::COMMON_TASK, diff --git a/js_concurrent_module/taskpool/task_group.cpp b/js_concurrent_module/taskpool/task_group.cpp index f5d61fe7..50cc7edc 100644 --- a/js_concurrent_module/taskpool/task_group.cpp +++ b/js_concurrent_module/taskpool/task_group.cpp @@ -119,7 +119,8 @@ napi_value TaskGroup::AddTask(napi_env env, napi_callback_info cbinfo) return nullptr; } else if (type == napi_function) { napi_value napiTask = NapiHelper::CreateObject(env); - Task* task = Task::GenerateFunctionTask(env, args[0], args + 1, argc - 1, TaskType::GROUP_FUNCTION_TASK); + Task* task = Task::GenerateGroupFunctionTask(env, args[0], args + 1, argc - 1, + TaskType::GROUP_FUNCTION_TASK, napiTask); if (task == nullptr) { return nullptr; } @@ -200,11 +201,7 @@ void TaskGroup::NotifyGroupTask(napi_env env) } napi_reference_ref(env, task->taskRef_, nullptr); Priority priority = currentGroupInfo_->priority; - if (task->IsGroupCommonTask()) { - task->GetTaskInfo(env, napiTask, priority); - } else { - reinterpret_cast(env)->IncreaseSubEnvCounter(); - } + task->GetTaskInfo(env, napiTask, priority); task->IncreaseRefCount(); TaskManager::GetInstance().IncreaseSendDataRefCount(task->taskId_); task->taskState_ = ExecuteState::WAITING; diff --git a/js_concurrent_module/taskpool/taskpool.cpp b/js_concurrent_module/taskpool/taskpool.cpp index 1a7b4db7..ec740c1b 100644 --- a/js_concurrent_module/taskpool/taskpool.cpp +++ b/js_concurrent_module/taskpool/taskpool.cpp @@ -375,9 +375,7 @@ napi_value TaskPool::ExecuteGroup(napi_env env, napi_value napiTaskGroup, Priori return nullptr; } napi_reference_ref(env, task->taskRef_, nullptr); - if (task->IsGroupCommonTask()) { - task->GetTaskInfo(env, napiTask, static_cast(priority)); - } + task->GetTaskInfo(env, napiTask, static_cast(priority)); ExecuteTask(env, task, static_cast(priority)); } } else { @@ -499,10 +497,8 @@ void TaskPool::UpdateGroupInfoByResult(napi_env env, Task* task, napi_value res, TaskManager::GetInstance().DecreaseSendDataRefCount(task->env_, task->taskId_); task->taskState_ = ExecuteState::FINISHED; napi_reference_unref(env, task->taskRef_, nullptr); - if (task->IsGroupCommonTask()) { - delete task->currentTaskInfo_; - task->currentTaskInfo_ = nullptr; - } + delete task->currentTaskInfo_; + task->currentTaskInfo_ = nullptr; TaskGroup* taskGroup = TaskGroupManager::GetInstance().GetTaskGroup(task->groupId_); if (taskGroup == nullptr || taskGroup->currentGroupInfo_ == nullptr) { HILOG_DEBUG("taskpool:: taskGroup may have been released or canceled"); -- Gitee