• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "sequence_runner.h"
16 
17 #include <cinttypes>
18 
19 #include "helper/error_helper.h"
20 #include "helper/napi_helper.h"
21 #include "helper/object_helper.h"
22 #include "task_manager.h"
23 #include "utils/log.h"
24 
25 namespace Commonlibrary::Concurrent::TaskPoolModule {
26 using namespace Commonlibrary::Concurrent::Common::Helper;
27 static constexpr char EXECUTE_STR[] = "execute";
28 static constexpr char SEQ_RUNNER_ID_STR[] = "seqRunnerId";
29 
SeqRunnerConstructor(napi_env env,napi_callback_info cbinfo)30 napi_value SequenceRunner::SeqRunnerConstructor(napi_env env, napi_callback_info cbinfo)
31 {
32     // get input args out of env and cbinfo
33     size_t argc = 1;
34     napi_value args[1];
35     napi_value thisVar;
36     napi_get_cb_info(env, cbinfo, &argc, args, &thisVar, nullptr);
37 
38     uint32_t priority = Priority::DEFAULT;
39     if (argc > 0) {
40         HILOG_DEBUG("seqRunner:: parse priority params.");
41         if (!NapiHelper::IsNumber(env, args[0])) {
42             ErrorHelper::ThrowError(env, ErrorHelper::TYPE_ERROR, "seqRunner:: first param must be priority.");
43             return nullptr;
44         }
45         priority = NapiHelper::GetUint32Value(env, args[0]);
46         if (priority >= Priority::NUMBER) {
47             ErrorHelper::ThrowError(env, ErrorHelper::TYPE_ERROR, "seqRunner:: priority value unvalied.");
48             return nullptr;
49         }
50     }
51     // update seqRunner.seqRunnerId
52     SequenceRunner* seqRunner = new SequenceRunner();
53     uint64_t seqRunnerId = reinterpret_cast<uint64_t>(seqRunner);
54     napi_value napiSeqRunnerId = NapiHelper::CreateUint64(env, seqRunnerId);
55     TaskGroupManager::GetInstance().StoreSequenceRunner(seqRunnerId, seqRunner);
56     napi_value seqRunnerExecuteFunc;
57     napi_create_function(env, EXECUTE_STR, NAPI_AUTO_LENGTH, Execute, NULL, &seqRunnerExecuteFunc);
58     napi_property_descriptor properties[] = {
59         DECLARE_NAPI_PROPERTY(SEQ_RUNNER_ID_STR, napiSeqRunnerId),
60         DECLARE_NAPI_FUNCTION(EXECUTE_STR, Execute),
61     };
62     napi_define_properties(env, thisVar, sizeof(properties) / sizeof(properties[0]), properties);
63     HILOG_DEBUG("seqRunner:: construct seqRunner %" PRIu64 ".", seqRunnerId);
64 
65     seqRunner->priority_ = Priority(priority);
66     seqRunner->seqRunnerId_ = seqRunnerId;
67     TaskGroupManager::GetInstance().StoreSequenceRunner(seqRunnerId, seqRunner);
68     napi_wrap(env, thisVar, seqRunner, SequnceRunnerDestructor, nullptr, nullptr);
69     napi_create_reference(env, thisVar, 0, &seqRunner->seqRunnerRef_);
70     return thisVar;
71 }
72 
Execute(napi_env env,napi_callback_info cbinfo)73 napi_value SequenceRunner::Execute(napi_env env, napi_callback_info cbinfo)
74 {
75     size_t argc = 1;
76     napi_value args[1];
77     napi_value thisVar;
78     napi_get_cb_info(env, cbinfo, &argc, args, &thisVar, nullptr);
79     std::string errMessage = "";
80     if (argc < 1) {
81         errMessage = "seqRunner:: number of params at least one";
82         HILOG_ERROR("%{public}s", errMessage.c_str());
83         ErrorHelper::ThrowError(env, ErrorHelper::TYPE_ERROR, errMessage.c_str());
84         return nullptr;
85     }
86     if (!NapiHelper::IsObject(env, args[0]) || !NapiHelper::HasNameProperty(env, args[0], TASKID_STR)) {
87         errMessage = "seqRunner:: first param must be task.";
88         HILOG_ERROR("%{public}s", errMessage.c_str());
89         ErrorHelper::ThrowError(env, ErrorHelper::TYPE_ERROR, errMessage.c_str());
90         return nullptr;
91     }
92     napi_value napiSeqRunnerId = NapiHelper::GetNameProperty(env, thisVar, SEQ_RUNNER_ID_STR);
93     uint64_t seqRunnerId = NapiHelper::GetUint64Value(env, napiSeqRunnerId);
94     SequenceRunner* seqRunner = TaskGroupManager::GetInstance().GetSeqRunner(seqRunnerId);
95     if (seqRunner == nullptr) {
96         return nullptr;
97     }
98     napi_reference_ref(env, seqRunner->seqRunnerRef_, nullptr);
99     Task* task = nullptr;
100     napi_unwrap(env, args[0], reinterpret_cast<void**>(&task));
101     if (task == nullptr) {
102         HILOG_ERROR("taskpool:: SeqRunner execute task is nullptr");
103         return nullptr;
104     }
105     if (!task->CanForSequenceRunner(env)) {
106         return nullptr;
107     }
108     task->seqRunnerId_ = seqRunnerId;
109     task->taskState_ = ExecuteState::WAITING;
110     napi_value promise = task->GetTaskInfoPromise(env, args[0], TaskType::SEQRUNNER_TASK, seqRunner->priority_);
111     if (promise == nullptr) {
112         return nullptr;
113     }
114     if (seqRunner->currentTaskId_ == 0) {
115         HILOG_DEBUG("seqRunner:: task %" PRIu64 " in seqRunner %" PRIu64 " immediately.", task->taskId_, seqRunnerId);
116         seqRunner->currentTaskId_ = task->taskId_;
117         task->IncreaseRefCount();
118         ExecuteTaskImmediately(task->taskId_, seqRunner->priority_);
119     } else {
120         HILOG_DEBUG("seqRunner:: add %" PRIu64 " to seqRunner %" PRIu64 ".", task->taskId_, seqRunnerId);
121         TaskGroupManager::GetInstance().AddTaskToSeqRunner(seqRunnerId, task);
122     }
123     return promise;
124 }
125 
ExecuteTaskImmediately(uint64_t taskId,Priority priority)126 void SequenceRunner::ExecuteTaskImmediately(uint64_t taskId, Priority priority)
127 {
128     TaskManager::GetInstance().EnqueueTaskId(taskId, priority);
129     TaskManager::GetInstance().TryTriggerExpand();
130 }
131 
SequnceRunnerDestructor(napi_env env,void * data,void * hint)132 void SequenceRunner::SequnceRunnerDestructor(napi_env env, void* data, [[maybe_unused]] void* hint)
133 {
134     SequenceRunner* seqRunner = static_cast<SequenceRunner*>(data);
135     TaskGroupManager::GetInstance().RemoveSequenceRunner(seqRunner->seqRunnerId_);
136     delete seqRunner;
137 }
138 }
139