From b8582c1e97f5c4f4d703a1267515d24f2e321d2d Mon Sep 17 00:00:00 2001 From: zhuruigan Date: Mon, 7 Jul 2025 11:14:07 +0800 Subject: [PATCH] modify asyncRunner lock Signed-off-by: zhuruigan Change-Id: Ib7eba723ac1c0c56dc68abb9253e18083b779acd --- .../taskpool/async_runner_manager.cpp | 20 ++-- js_concurrent_module/taskpool/test/test.cpp | 8 ++ js_concurrent_module/taskpool/test/test.h | 1 + .../taskpool/test/test_taskpool.cpp | 103 ++++++++++++++++++ 4 files changed, 125 insertions(+), 7 deletions(-) diff --git a/js_concurrent_module/taskpool/async_runner_manager.cpp b/js_concurrent_module/taskpool/async_runner_manager.cpp index e1b91b4f..8b8c19fd 100644 --- a/js_concurrent_module/taskpool/async_runner_manager.cpp +++ b/js_concurrent_module/taskpool/async_runner_manager.cpp @@ -33,23 +33,27 @@ AsyncRunner* AsyncRunnerManager::CreateOrGetGlobalRunner(napi_env env, napi_valu uint32_t runningCapacity, uint32_t waitingCapacity) { AsyncRunner *asyncRunner = nullptr; + bool isNew = false; + uint64_t asyncRunnerId = 0; { std::unique_lock lock(globalAsyncRunnerMutex_); auto iter = globalAsyncRunner_.find(name); if (iter == globalAsyncRunner_.end()) { asyncRunner = AsyncRunner::CreateGlobalRunner(name, runningCapacity, waitingCapacity); globalAsyncRunner_.emplace(name, asyncRunner); + isNew = true; } else { asyncRunner = iter->second; bool res = asyncRunner->CheckGlobalRunnerParams(env, runningCapacity, waitingCapacity); if (!res) { return nullptr; } - if (!FindRunnerAndRef(asyncRunner->asyncRunnerId_)) { - return nullptr; - } + asyncRunnerId = asyncRunner->asyncRunnerId_; } } + if (!isNew && !FindRunnerAndRef(asyncRunnerId)) { + return nullptr; + } return asyncRunner; } @@ -150,14 +154,16 @@ bool AsyncRunnerManager::FindRunnerAndRef(uint64_t asyncRunnerId) bool AsyncRunnerManager::UnrefAndDestroyRunner(AsyncRunner* asyncRunner) { - std::unique_lock lock(asyncRunnersMutex_); - if (asyncRunner->DecreaseAsyncCount() != 0) { - return false; + { + std::unique_lock lock(asyncRunnersMutex_); + if (asyncRunner->DecreaseAsyncCount() != 0) { + return false; + } + RemoveAsyncRunner(asyncRunner->asyncRunnerId_); } if (asyncRunner->isGlobalRunner_) { RemoveGlobalAsyncRunner(asyncRunner->name_); } - RemoveAsyncRunner(asyncRunner->asyncRunnerId_); delete asyncRunner; asyncRunner = nullptr; return true; diff --git a/js_concurrent_module/taskpool/test/test.cpp b/js_concurrent_module/taskpool/test/test.cpp index e8db359b..203dccc0 100755 --- a/js_concurrent_module/taskpool/test/test.cpp +++ b/js_concurrent_module/taskpool/test/test.cpp @@ -1050,4 +1050,12 @@ void NativeEngineTest::SetNonIdleTaskNum(uint32_t num) TaskManager& taskManager = TaskManager::GetInstance(); taskManager.nonIdleTaskNum_ = num; } + +void NativeEngineTest::EnqueueTaskIdToQueue(void* data) +{ + TaskManager& taskManager = TaskManager::GetInstance(); + Task* task = reinterpret_cast(data); + auto& taskQueue = taskManager.taskQueues_[task->asyncTaskPriority_]; + taskQueue->EnqueueTaskId(task->taskId_); +} } // namespace Commonlibrary::Concurrent::TaskPoolModule \ No newline at end of file diff --git a/js_concurrent_module/taskpool/test/test.h b/js_concurrent_module/taskpool/test/test.h index c2036f75..7ef8c540 100644 --- a/js_concurrent_module/taskpool/test/test.h +++ b/js_concurrent_module/taskpool/test/test.h @@ -95,6 +95,7 @@ public: static void GetIdleTaskByPriority(napi_env env); static void WorkerRunningScope(napi_env env); static void SetNonIdleTaskNum(uint32_t num); + static void EnqueueTaskIdToQueue(void* data); class ExceptionScope { public: diff --git a/js_concurrent_module/taskpool/test/test_taskpool.cpp b/js_concurrent_module/taskpool/test/test_taskpool.cpp index eb874b2f..ede20a55 100644 --- a/js_concurrent_module/taskpool/test/test_taskpool.cpp +++ b/js_concurrent_module/taskpool/test/test_taskpool.cpp @@ -6426,4 +6426,107 @@ HWTEST_F(NativeEngineTest, TaskpoolTest317, testing::ext::TestSize.Level0) napi_value exception = nullptr; napi_get_and_clear_last_exception(env, &exception); ASSERT_TRUE(exception == nullptr); +} + +HWTEST_F(NativeEngineTest, TaskpoolTest318, testing::ext::TestSize.Level0) +{ + napi_env env = (napi_env)engine_; + ExceptionScope scope(env); + AsyncRunnerManager &asyncRunnerManager = AsyncRunnerManager::GetInstance(); + TaskManager &taskManager = TaskManager::GetInstance(); + Task* task = new Task(); + task->taskId_ = taskManager.CalculateTaskId(reinterpret_cast(task)); + task->taskState_ = ExecuteState::RUNNING; + asyncRunnerManager.CancelAsyncRunnerTask(env, task); + napi_value exception = nullptr; + napi_get_and_clear_last_exception(env, &exception); + ASSERT_TRUE(exception == nullptr); + delete task; + + Task* task2 = new Task(); + task2->taskId_ = taskManager.CalculateTaskId(reinterpret_cast(task2)); + task2->taskState_ = ExecuteState::WAITING; + asyncRunnerManager.CancelAsyncRunnerTask(env, task2); + exception = nullptr; + napi_get_and_clear_last_exception(env, &exception); + ASSERT_TRUE(exception == nullptr); + delete task2; + + Task* task3 = new Task(); + task3->taskId_ = taskManager.CalculateTaskId(reinterpret_cast(task3)); + TaskInfo* taskInfo = new TaskInfo(); + task3->currentTaskInfo_ = taskInfo; + task3->taskType_ = TaskType::ASYNCRUNNER_TASK; + task3->taskState_ = ExecuteState::WAITING; + asyncRunnerManager.CancelAsyncRunnerTask(env, task3); + exception = nullptr; + napi_get_and_clear_last_exception(env, &exception); + ASSERT_TRUE(exception == nullptr); + delete task3; + delete taskInfo; +} + +HWTEST_F(NativeEngineTest, TaskpoolTest319, testing::ext::TestSize.Level0) +{ + napi_env env = (napi_env)engine_; + ExceptionScope scope(env); + AsyncRunnerManager &asyncRunnerManager = AsyncRunnerManager::GetInstance(); + TaskManager &taskManager = TaskManager::GetInstance(); + + Task* task = new Task(); + TaskInfo* taskInfo = new TaskInfo(); + task->currentTaskInfo_ = taskInfo; + task->taskType_ = TaskType::ASYNCRUNNER_TASK; + task->taskState_ = ExecuteState::WAITING; + taskManager.StoreTask(task); + NativeEngineTest::EnqueueTaskIdToQueue(reinterpret_cast(task)); + asyncRunnerManager.CancelAsyncRunnerTask(env, task); + napi_value exception = nullptr; + napi_get_and_clear_last_exception(env, &exception); + ASSERT_TRUE(exception == nullptr); + taskManager.RemoveTask(task->taskId_); + delete task; + + AsyncRunner* asyncRunner = new AsyncRunner(); + asyncRunner->asyncRunnerId_ = reinterpret_cast(asyncRunner); + asyncRunnerManager.StoreAsyncRunner(asyncRunner->asyncRunnerId_, asyncRunner); + Task* task2 = new Task(); + TaskInfo* taskInfo2 = new TaskInfo(); + task2->currentTaskInfo_ = taskInfo2; + task2->taskType_ = TaskType::ASYNCRUNNER_TASK; + task2->taskState_ = ExecuteState::WAITING; + taskManager.StoreTask(task2); + task2->asyncRunnerId_ = asyncRunner->asyncRunnerId_; + NativeEngineTest::EnqueueTaskIdToQueue(reinterpret_cast(task2)); + asyncRunnerManager.CancelAsyncRunnerTask(env, task2); + exception = nullptr; + napi_get_and_clear_last_exception(env, &exception); + ASSERT_TRUE(exception == nullptr); + taskManager.RemoveTask(task2->taskId_); +} + +HWTEST_F(NativeEngineTest, TaskpoolTest320, testing::ext::TestSize.Level0) +{ + napi_env env = (napi_env)engine_; + ExceptionScope scope(env); + AsyncRunnerManager &asyncRunnerManager = AsyncRunnerManager::GetInstance(); + TaskManager &taskManager = TaskManager::GetInstance(); + Task* task = new Task(); + asyncRunnerManager.RemoveWaitingTask(task); + napi_value exception = nullptr; + napi_get_and_clear_last_exception(env, &exception); + ASSERT_TRUE(exception == nullptr); + + AsyncRunner* asyncRunner = new AsyncRunner(); + asyncRunner->asyncRunnerId_ = reinterpret_cast(asyncRunner); + asyncRunnerManager.StoreAsyncRunner(asyncRunner->asyncRunnerId_, asyncRunner); + Task* task2 = new Task(); + task2->asyncRunnerId_ = asyncRunner->asyncRunnerId_; + asyncRunnerManager.RemoveWaitingTask(task2); + exception = nullptr; + napi_get_and_clear_last_exception(env, &exception); + ASSERT_TRUE(exception == nullptr); + + delete task; + delete task2; } \ No newline at end of file -- Gitee