From 2bb9526cb8e2b6a4e09e403a4c1470ec02a34c10 Mon Sep 17 00:00:00 2001 From: wangzhen Date: Tue, 5 Nov 2024 19:34:07 +0800 Subject: [PATCH] Add task timeout Signed-off-by: wangzhen Change-Id: I0235a8aeeee49d9d15a2aaac05cfb5c15b83aba8 --- services/appmgr/src/ams_mgr_scheduler.cpp | 24 +++++----- services/common/include/task_handler_wrap.h | 12 +++-- services/common/include/task_utils_wrap.h | 7 +-- .../common/src/ffrt_task_handler_wrap.cpp | 12 ++--- services/common/src/ffrt_task_handler_wrap.h | 1 + .../common/src/queue_task_handler_wrap.cpp | 24 +++++----- services/common/src/queue_task_handler_wrap.h | 1 + services/common/src/task_handler_wrap.cpp | 26 +++++------ .../include/mock_task_handler_wrap.h | 2 +- .../task_handler_wrap_test.cpp | 44 ++++++++++++++++++- 10 files changed, 97 insertions(+), 56 deletions(-) diff --git a/services/appmgr/src/ams_mgr_scheduler.cpp b/services/appmgr/src/ams_mgr_scheduler.cpp index 88729a5e00..417a25fa1f 100644 --- a/services/appmgr/src/ams_mgr_scheduler.cpp +++ b/services/appmgr/src/ams_mgr_scheduler.cpp @@ -51,8 +51,9 @@ constexpr const char* SCENEBOARD_ABILITY_NAME = "com.ohos.sceneboard.MainAbility constexpr const char* TASK_SCENE_BOARD_ATTACH_TIMEOUT = "sceneBoardAttachTimeoutTask"; constexpr const char* TASK_ATTACHED_TO_STATUS_BAR = "AttachedToStatusBar"; constexpr const char* TASK_BLOCK_PROCESS_CACHE_BY_PIDS = "BlockProcessCacheByPids"; +constexpr const char* POWER_OFF_ABILITY = "BlockProcessCacheByPids"; constexpr int32_t SCENE_BOARD_ATTACH_TIMEOUT_TASK_TIME = 1000; -constexpr const char* TASK_LOAD_ABILITY = "LoadAbilityTask"; +constexpr int32_t LOAD_TASK_TIMEOUT = 30000; // ms }; // namespace AmsMgrScheduler::AmsMgrScheduler( @@ -109,19 +110,20 @@ void AmsMgrScheduler::LoadAbility(const std::shared_ptr &abilityInf amsHandler_->SubmitTask(timeoutTask, TASK_SCENE_BOARD_ATTACH_TIMEOUT, SCENE_BOARD_ATTACH_TIMEOUT_TASK_TIME); } + AAFwk::TaskAttribute taskAttr{ + .taskName_ = "LoadAbilityTask", + .taskQos_ = AAFwk::TaskQoS::USER_INTERACTIVE, + .timeoutMillis_ = LOAD_TASK_TIMEOUT + }; + if (abilityInfo->bundleName == AAFwk::AppUtils::GetInstance().GetMigrateClientBundleName()) { - amsHandler_->SubmitTask(loadAbilityFunc, AAFwk::TaskAttribute{ - .taskName_ = TASK_LOAD_ABILITY, - .taskQos_ = AAFwk::TaskQoS::USER_INTERACTIVE, - .taskPriority_ = AAFwk::TaskQueuePriority::IMMEDIATE - }); - return; + taskAttr.taskPriority_ = AAFwk::TaskQueuePriority::IMMEDIATE; + } + if (abilityInfo->bundleName == SCENE_BOARD_BUNDLE_NAME && abilityInfo->name == POWER_OFF_ABILITY) { + taskAttr.insertHead_ = true; } - amsHandler_->SubmitTask(loadAbilityFunc, AAFwk::TaskAttribute{ - .taskName_ = TASK_LOAD_ABILITY, - .taskQos_ = AAFwk::TaskQoS::USER_INTERACTIVE, - }); + amsHandler_->SubmitTask(loadAbilityFunc, taskAttr); } void AmsMgrScheduler::UpdateAbilityState(const sptr &token, const AbilityState state) diff --git a/services/common/include/task_handler_wrap.h b/services/common/include/task_handler_wrap.h index ec7d786e71..50862c802c 100644 --- a/services/common/include/task_handler_wrap.h +++ b/services/common/include/task_handler_wrap.h @@ -93,22 +93,26 @@ public: TaskHandle SubmitTask(const std::function &task, const std::string &name, int64_t delayMillis, bool forceSubmit = true); TaskHandle SubmitTask(const std::function &task, const TaskAttribute &taskAttr); - // Task can't be canceled by name if submited with this mothed + // Task can't be canceled by name if submitted with this method TaskHandle SubmitTaskJust(const std::function &task, const std::string &name, int64_t delayMillis); - // This is only used for compatibility and could be be wrong if multi tasks with same name submited. - // TaskHandle::Cancel is prefered. + // This is only used for compatibility and could be be wrong if multi tasks with same name submitted. + // TaskHandle::Cancel is preferred. bool CancelTask(const std::string &name); void SetPrintTaskLog(bool printTaskLog) { printTaskLog_ = printTaskLog; } protected: - TaskHandlerWrap(); + TaskHandlerWrap(const std::string &queueName); virtual std::shared_ptr SubmitTaskInner(std::function &&task, const TaskAttribute &taskAttr) = 0; virtual bool CancelTaskInner(const std::shared_ptr &taskHandle) = 0; virtual void WaitTaskInner(const std::shared_ptr &taskHandle) = 0; + virtual uint64_t GetTaskCount() + { + return 0; + } bool RemoveTask(const std::string &name, const TaskHandle &taskHandle); protected: static std::atomic_int32_t g_taskId; diff --git a/services/common/include/task_utils_wrap.h b/services/common/include/task_utils_wrap.h index fde99e7b90..0f3038a2a0 100644 --- a/services/common/include/task_utils_wrap.h +++ b/services/common/include/task_utils_wrap.h @@ -48,11 +48,8 @@ struct TaskAttribute { int64_t delayMillis_ = 0; TaskQoS taskQos_ = TaskQoS::DEFAULT; TaskQueuePriority taskPriority_ = TaskQueuePriority::LOW; - - bool IsDefault() const - { - return delayMillis_ <= 0 && taskName_.empty() && taskQos_ == TaskQoS::DEFAULT; - } + int64_t timeoutMillis_ = 0; // task should be started within timeout + bool insertHead_ = false; // insert into the head of the queue }; } // namespace AAFwk } // namespace OHOS diff --git a/services/common/src/ffrt_task_handler_wrap.cpp b/services/common/src/ffrt_task_handler_wrap.cpp index cd512176e7..025f73744b 100644 --- a/services/common/src/ffrt_task_handler_wrap.cpp +++ b/services/common/src/ffrt_task_handler_wrap.cpp @@ -20,14 +20,10 @@ namespace AAFwk { std::shared_ptr FfrtTaskHandlerWrap::SubmitTaskInner(std::function &&task, const TaskAttribute &taskAttr) { - if (taskAttr.IsDefault()) { - return std::make_shared(ffrt::submit_h(std::move(task))); - } else { - ffrt::task_attr ffrtTaskAttr; - BuildFfrtTaskAttr(taskAttr, ffrtTaskAttr); - return std::make_shared(ffrt::submit_h(std::move(task), - {}, {}, ffrtTaskAttr)); - } + ffrt::task_attr ffrtTaskAttr; + BuildFfrtTaskAttr(taskAttr, ffrtTaskAttr); + return std::make_shared(ffrt::submit_h(std::move(task), + {}, {}, ffrtTaskAttr)); } bool FfrtTaskHandlerWrap::CancelTaskInner(const std::shared_ptr &taskHandle) diff --git a/services/common/src/ffrt_task_handler_wrap.h b/services/common/src/ffrt_task_handler_wrap.h index e5bc4e7880..1c62140594 100644 --- a/services/common/src/ffrt_task_handler_wrap.h +++ b/services/common/src/ffrt_task_handler_wrap.h @@ -24,6 +24,7 @@ namespace AAFwk { class FfrtTaskHandlerWrap : public TaskHandlerWrap { public: virtual ~FfrtTaskHandlerWrap() = default; + FfrtTaskHandlerWrap() : TaskHandlerWrap("ffrt") {} protected: std::shared_ptr SubmitTaskInner(std::function &&task, diff --git a/services/common/src/queue_task_handler_wrap.cpp b/services/common/src/queue_task_handler_wrap.cpp index 08f87c4275..379cbe6fcc 100644 --- a/services/common/src/queue_task_handler_wrap.cpp +++ b/services/common/src/queue_task_handler_wrap.cpp @@ -15,16 +15,16 @@ #include "queue_task_handler_wrap.h" - namespace OHOS { namespace AAFwk { constexpr int32_t QUEUE_TIME_OUT = 500000; // us QueueTaskHandlerWrap::QueueTaskHandlerWrap(const std::string &queueName, TaskQoS queueQos) - : taskQueue_(queueName.c_str(), ffrt::queue_attr().qos(Convert2FfrtQos(queueQos)).timeout(QUEUE_TIME_OUT)) + : TaskHandlerWrap(queueName), + taskQueue_(queueName.c_str(), ffrt::queue_attr().qos(Convert2FfrtQos(queueQos)).timeout(QUEUE_TIME_OUT)) {} QueueTaskHandlerWrap::QueueTaskHandlerWrap(const std::string &queueName, int32_t concurrentNum, TaskQoS queueQos) - : taskQueue_( + : TaskHandlerWrap(queueName), taskQueue_( ffrt::queue_type::queue_concurrent, queueName.c_str(), ffrt::queue_attr().qos(Convert2FfrtQos(queueQos)).timeout(QUEUE_TIME_OUT).max_concurrency(concurrentNum)) @@ -33,15 +33,14 @@ QueueTaskHandlerWrap::QueueTaskHandlerWrap(const std::string &queueName, int32_t std::shared_ptr QueueTaskHandlerWrap::SubmitTaskInner(std::function &&task, const TaskAttribute &taskAttr) { - if (taskAttr.IsDefault()) { - return std::make_shared(taskQueue_.submit_h(std::move(task))); - } else { - ffrt::task_attr ffrtTaskAttr; - BuildFfrtTaskAttr(taskAttr, ffrtTaskAttr); - return std::make_shared(taskQueue_.submit_h(std::move(task), - ffrtTaskAttr)); + ffrt::task_attr ffrtTaskAttr{}; + BuildFfrtTaskAttr(taskAttr, ffrtTaskAttr); + if (taskAttr.insertHead_) { + return std::make_shared(taskQueue_.submit_head_h(std::move(task), ffrtTaskAttr)); } + return std::make_shared(taskQueue_.submit_h(std::move(task), ffrtTaskAttr)); } + bool QueueTaskHandlerWrap::CancelTaskInner(const std::shared_ptr &taskHandle) { if (!taskHandle) { @@ -56,5 +55,10 @@ void QueueTaskHandlerWrap::WaitTaskInner(const std::shared_ptr } taskQueue_.wait(taskHandle->GetFfrtHandle()); } + +uint64_t QueueTaskHandlerWrap::GetTaskCount() +{ + return taskQueue_.get_task_cnt(); +} } // namespace AAFwk } // namespace OHOS \ No newline at end of file diff --git a/services/common/src/queue_task_handler_wrap.h b/services/common/src/queue_task_handler_wrap.h index 8a14e10250..596bb04313 100644 --- a/services/common/src/queue_task_handler_wrap.h +++ b/services/common/src/queue_task_handler_wrap.h @@ -32,6 +32,7 @@ protected: const TaskAttribute &taskAttr) override; bool CancelTaskInner(const std::shared_ptr &taskHandle) override; void WaitTaskInner(const std::shared_ptr &taskHandle) override; + uint64_t GetTaskCount() override; private: ffrt::queue taskQueue_; }; diff --git a/services/common/src/task_handler_wrap.cpp b/services/common/src/task_handler_wrap.cpp index 5eb7f2f74b..8418871e69 100644 --- a/services/common/src/task_handler_wrap.cpp +++ b/services/common/src/task_handler_wrap.cpp @@ -15,6 +15,7 @@ #include "task_handler_wrap.h" +#include #include #include "cpp/mutex.h" #include "hilog_tag_wrapper.h" @@ -46,12 +47,12 @@ void TaskHandle::Sync() const { auto handler = handler_.lock(); if (!status_ || !handler || !innerTaskHandle_) { - TAG_LOGE(AAFwkTag::DEFAULT, "Invalid status"); + TAG_LOGI(AAFwkTag::DEFAULT, "Invalid status"); return; } auto &status = *status_; if (status == TaskStatus::FINISHED || status == TaskStatus::CANCELED) { - TAG_LOGE(AAFwkTag::DEFAULT, "Invalid status"); + TAG_LOGI(AAFwkTag::DEFAULT, "Invalid status"); return; } handler->WaitTaskInner(innerTaskHandle_); @@ -62,17 +63,13 @@ std::atomic_int32_t TaskHandlerWrap::g_taskId = 0; std::shared_ptr TaskHandlerWrap::CreateQueueHandler(const std::string &queueName, TaskQoS queueQos) { - auto result = std::make_shared(queueName, queueQos); - result->queueName_ = queueName; - return result; + return std::make_shared(queueName, queueQos); } std::shared_ptr TaskHandlerWrap::CreateConcurrentQueueHandler(const std::string &queueName, int32_t concurrentNum, TaskQoS queueQos) { - auto result = std::make_shared(queueName, concurrentNum, queueQos); - result->queueName_ = queueName; - return result; + return std::make_shared(queueName, concurrentNum, queueQos); } std::shared_ptr TaskHandlerWrap::GetFfrtHandler() @@ -81,7 +78,7 @@ std::shared_ptr TaskHandlerWrap::GetFfrtHandler() return ffrtHandler; } -TaskHandlerWrap::TaskHandlerWrap() +TaskHandlerWrap::TaskHandlerWrap(const std::string &queueName) : queueName_(queueName) { tasksMutex_ = std::make_unique(); } @@ -157,15 +154,11 @@ TaskHandle TaskHandlerWrap::SubmitTask(const std::function &task, const *result.status_ = TaskStatus::EXECUTING; task(); *result.status_ = TaskStatus::FINISHED; - if (result.PrintTaskLog()) { - TAG_LOGW(AAFwkTag::DEFAULT, "end execute task name: %{public}s, taskId: %{public}d", - taskName.c_str(), result.GetTaskId()); - } }; if (printTaskLog_) { - TAG_LOGW(AAFwkTag::DEFAULT, "submit task name: %{public}s, taskId: %{public}d, queueName: %{public}s", - taskAttr.taskName_.c_str(), result.taskId_, queueName_.c_str()); + TAG_LOGW(AAFwkTag::DEFAULT, "submitTask: %{public}s, taskId: %{public}d, queueName: %{public}s count: " + "%{public}" PRIu64"", taskAttr.taskName_.c_str(), result.taskId_, queueName_.c_str(), GetTaskCount()); } result.innerTaskHandle_ = SubmitTaskInner(std::move(taskWrap), taskAttr); return result; @@ -253,6 +246,9 @@ void BuildFfrtTaskAttr(const TaskAttribute &taskAttr, ffrt::task_attr &result) if (taskAttr.taskPriority_ != TaskQueuePriority::LOW) { result.priority(Convert2FfrtPriority(taskAttr.taskPriority_)); } + if (taskAttr.timeoutMillis_ > 0) { + result.timeout(taskAttr.timeoutMillis_ * MILL_TO_MICRO); + } } } // namespace AAFWK } // namespace OHOS \ No newline at end of file diff --git a/test/mock/task_handler_wrap_mock/include/mock_task_handler_wrap.h b/test/mock/task_handler_wrap_mock/include/mock_task_handler_wrap.h index 9d246c01d0..20332458d1 100644 --- a/test/mock/task_handler_wrap_mock/include/mock_task_handler_wrap.h +++ b/test/mock/task_handler_wrap_mock/include/mock_task_handler_wrap.h @@ -33,7 +33,7 @@ public: { return std::make_shared(); } - MockTaskHandlerWrap() = default; + MockTaskHandlerWrap() : TaskHandlerWrap("MockTaskHandlerWrap") {} MockTaskHandlerWrap(TaskHandlerWrap &) = delete; void operator=(MockTaskHandlerWrap &) = delete; virtual ~MockTaskHandlerWrap() {} diff --git a/test/unittest/task_handler_wrap_test/task_handler_wrap_test.cpp b/test/unittest/task_handler_wrap_test/task_handler_wrap_test.cpp index 37b964d981..a1c76795e0 100644 --- a/test/unittest/task_handler_wrap_test/task_handler_wrap_test.cpp +++ b/test/unittest/task_handler_wrap_test/task_handler_wrap_test.cpp @@ -21,7 +21,8 @@ using namespace testing::ext; namespace OHOS { namespace AAFwk { -constexpr int32_t LONG_TIME_TASK_TIME = 2 * 500000 + 100000; +constexpr int32_t LONG_TIME_TASK_TIME = 2 * 500000 + 100000; // us +constexpr int32_t SCHEDULE_TIMEOUT = 500; // ms class TaskHandlerWrapTest : public testing::Test { public: static void SetUpTestCase(void); @@ -107,7 +108,7 @@ HWTEST_F(TaskHandlerWrapTest, QueueTest_0040, TestSize.Level0) } /** - * @tc.name: QueueTest_0040 + * @tc.name: QueueTest_0050 * @tc.desc: SubmitTask time task test * @tc.type: FUNC */ @@ -123,6 +124,45 @@ HWTEST_F(TaskHandlerWrapTest, QueueTest_0050, TestSize.Level0) EXPECT_TRUE(input == 1); } +/** + * @tc.name: QueueTest_0060 + * @tc.desc: Insert task test + * @tc.type: FUNC + */ +HWTEST_F(TaskHandlerWrapTest, QueueTest_0060, TestSize.Level0) +{ + queueHandler_->SetPrintTaskLog(true); + int input = 0; + auto task1 = [&input]() { + usleep(LONG_TIME_TASK_TIME); + input = 1; + }; + auto handle1 = queueHandler_->SubmitTask(task1, "task1"); + + // this task will trigger scheduling timeout + auto handle2 = queueHandler_->SubmitTask([](){}, TaskAttribute{ + .taskName_ = "task2", + .timeoutMillis_ = SCHEDULE_TIMEOUT + }); + + int result3 = 0; + int result4 = 0; + auto handle3 = queueHandler_->SubmitTask([&input, &result3]() { + result3 = ++input; + }, "task3"); + auto handle4 = queueHandler_->SubmitTask([&input, &result4]() { + result4 = ++input; + }, TaskAttribute{ + .taskName_ = "task4", + .insertHead_ = true + }); + handle1.Sync(); + handle2.Sync(); + handle3.Sync(); + handle4.Sync(); + EXPECT_TRUE(result3 == result4 + 1); +} + /** * @tc.name: FfrtTest_0010 * @tc.desc: SubmitTask Test