1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "task_registry.h"
17 #include "delayed_task_group.h"
18 #include "task_group.h"
19 #include "dp_log.h"
20 
21 namespace OHOS {
22 namespace CameraStandard {
23 namespace DeferredProcessing {
TaskRegistry(const std::string & name,const ThreadPool * threadPool)24 TaskRegistry::TaskRegistry(const std::string& name, const ThreadPool* threadPool)
25     : name_(name), threadPool_(threadPool), mutex_(), registry_()
26 {
27     DP_DEBUG_LOG("name: %s.", name.c_str());
28 }
29 
~TaskRegistry()30 TaskRegistry::~TaskRegistry()
31 {
32     CAMERA_DP_SYNC_TRACE;
33     DP_DEBUG_LOG("name: %s.", name_.c_str());
34     std::lock_guard<std::mutex> lock(mutex_);
35     registry_.clear();
36 }
37 
RegisterTaskGroup(const std::string & name,TaskFunc func,bool serial,bool delayTask,TaskGroupHandle & handle)38 bool TaskRegistry::RegisterTaskGroup(const std::string& name, TaskFunc func, bool serial, bool delayTask,
39     TaskGroupHandle& handle)
40 {
41     DP_DEBUG_LOG("name: %s, serial: %{public}d, delayTask: %{public}d.", name.c_str(), serial, delayTask);
42     if (IsTaskGroupAlreadyRegistered(name)) {
43         DP_DEBUG_LOG("failed, task group (%s) already existed!", name.c_str());
44         return false;
45     }
46     std::lock_guard<std::mutex> lock(mutex_);
47     std::shared_ptr<ITaskGroup> taskGroup = [delayTask, &name, func = std::move(func), serial, pool = threadPool_] () {
48         if (delayTask) {
49             std::shared_ptr<ITaskGroup> ret = std::make_shared<DelayedTaskGroup>(name, std::move(func), pool);
50             return ret;
51         } else {
52             std::shared_ptr<ITaskGroup> ret = std::make_shared<TaskGroup>(name, std::move(func), serial, pool);
53             return ret;
54         }
55     }();
56     handle = taskGroup->GetHandle();
57     registry_.emplace(handle, taskGroup);
58     return true;
59 }
60 
DeregisterTaskGroup(const std::string & name,TaskGroupHandle & handle)61 bool TaskRegistry::DeregisterTaskGroup(const std::string& name, TaskGroupHandle& handle)
62 {
63     CAMERA_DP_SYNC_TRACE;
64     DP_DEBUG_LOG("name: %s.", name.c_str());
65     if (!IsTaskGroupAlreadyRegistered(name)) {
66         DP_DEBUG_LOG("name: %s, with handle:%{public}d, failed due to non exist task group!",
67             name.c_str(), static_cast<int>(handle));
68         return false;
69     }
70     std::lock_guard<std::mutex> lock(mutex_);
71     auto it = registry_.find(handle);
72     if (it == registry_.end()) {
73         DP_DEBUG_LOG("name: %s, handle:%{public}d failed due to non-existent task group!",
74             name.c_str(), static_cast<int>(handle));
75         return false;
76     }
77     registry_.erase(it);
78     return true;
79 }
80 
SubmitTask(TaskGroupHandle handle,std::any param)81 bool TaskRegistry::SubmitTask(TaskGroupHandle handle, std::any param)
82 {
83     DP_DEBUG_LOG("submit one task to %{public}d", static_cast<int>(handle));
84     std::lock_guard<std::mutex> lock(mutex_);
85     auto it = registry_.find(handle);
86     if (it == registry_.end()) {
87         DP_DEBUG_LOG("failed due to task group %{public}d non-exist!", static_cast<int>(handle));
88         return false;
89     }
90     return it->second->SubmitTask(std::move(param));
91 }
92 
CancelAllTasks(TaskGroupHandle handle)93 void TaskRegistry::CancelAllTasks(TaskGroupHandle handle)
94 {
95     DP_DEBUG_LOG("Cancel all tasks to %{public}d", static_cast<int>(handle));
96     std::lock_guard<std::mutex> lock(mutex_);
97     auto it = registry_.find(handle);
98     if (it == registry_.end()) {
99         DP_DEBUG_LOG("failed due to task group %{public}d non-exist!", static_cast<int>(handle));
100         return;
101     }
102     it->second->CancelAllTasks();
103 }
104 
GetTaskCount(TaskGroupHandle handle)105 size_t TaskRegistry::GetTaskCount(TaskGroupHandle handle)
106 {
107     DP_DEBUG_LOG("Get task count %{public}d", static_cast<int>(handle));
108     std::lock_guard<std::mutex> lock(mutex_);
109     auto it = registry_.find(handle);
110     if (it == registry_.end()) {
111         DP_DEBUG_LOG("failed due to task group %{public}d non-exist!", static_cast<int>(handle));
112         return 0;
113     }
114     return it->second->GetTaskCount();
115 }
116 
IsTaskGroupAlreadyRegistered(const std::string & name)117 bool TaskRegistry::IsTaskGroupAlreadyRegistered(const std::string& name)
118 {
119     std::lock_guard<std::mutex> lock(mutex_);
120     for (auto it = registry_.begin(); it != registry_.end(); ++it) {
121         if (it->second->GetName() == name) {
122             DP_DEBUG_LOG("task group (%s) had registered.", name.c_str());
123             return true;
124         }
125     }
126     DP_DEBUG_LOG("task group (%s) hasn't been registered.", name.c_str());
127     return false;
128 }
129 } //namespace DeferredProcessing
130 } // namespace CameraStandard
131 } // namespace OHOS
132