1 /* 2 * Copyright (c) 2022 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 #ifndef JS_CONCURRENT_MODULE_TASKPOOL_TASKPOOL_H 17 #define JS_CONCURRENT_MODULE_TASKPOOL_TASKPOOL_H 18 19 #include "napi/native_api.h" 20 #include "napi/native_node_api.h" 21 #include "native_engine/native_engine.h" 22 #include "task.h" 23 #include "task_group.h" 24 25 namespace Commonlibrary::Concurrent::TaskPoolModule { 26 using namespace Commonlibrary::Concurrent::Common; 27 28 struct TaskMessage { 29 napi_deferred deferred = nullptr; 30 Priority priority {Priority::DEFAULT}; 31 uint64_t taskId {}; 32 }; 33 34 class TaskPool { 35 public: 36 static napi_value InitTaskPool(napi_env env, napi_value exports); 37 static void ExecuteCallback(const uv_async_t* req); 38 static void ExecuteCallbackTask(CallbackInfo* callbackInfo); 39 static void HandleTaskResult(const uv_async_t* req); 40 static void HandleTaskResultCallback(Task* task); 41 42 private: 43 TaskPool() = delete; 44 ~TaskPool() = delete; 45 TaskPool(const TaskPool &) = delete; 46 TaskPool& operator=(const TaskPool &) = delete; 47 TaskPool(TaskPool &&) = delete; 48 TaskPool& operator=(TaskPool &&) = delete; 49 50 static napi_value Execute(napi_env env, napi_callback_info cbinfo); 51 static napi_value ExecuteDelayed(napi_env env, napi_callback_info cbinfo); 52 static void DelayTask(uv_timer_t* handle); 53 static napi_value Cancel(napi_env env, napi_callback_info cbinfo); 54 static napi_value GetTaskPoolInfo(napi_env env, [[maybe_unused]] napi_callback_info cbinfo); 55 static napi_value TerminateTask(napi_env env, napi_callback_info cbinfo); 56 static napi_value IsConcurrent(napi_env env, napi_callback_info cbinfo); 57 static napi_value ExecutePeriodically(napi_env env, napi_callback_info cbinfo); 58 static void PeriodicTaskCallback(uv_timer_t* handle); 59 60 static void UpdateGroupInfoByResult(napi_env env, Task* task, napi_value res, bool success); 61 static void ExecuteTask(napi_env env, Task* task, Priority priority = Priority::DEFAULT); 62 static napi_value ExecuteGroup(napi_env env, napi_value taskGroup, Priority priority); 63 64 static void TriggerTask(Task* task); 65 static void TriggerTimer(napi_env env, Task* task, int32_t period); 66 static void ExecuteCallbackInner(MsgQueue& msgQueue); 67 static bool CheckDelayedParams(napi_env env, napi_callback_info cbinfo, uint32_t &priority, int32_t &delayTime, 68 Task* &task); 69 static bool CheckPeriodicallyParams(napi_env env, napi_callback_info cbinfo, int32_t &period, uint32_t &priority, 70 Task* &task); 71 friend class TaskManager; 72 friend class NativeEngineTest; 73 }; 74 75 class CallbackScope { 76 public: CallbackScope(napi_env env,napi_env workerEnv,uint64_t taskId,napi_status & status)77 CallbackScope(napi_env env, napi_env workerEnv, uint64_t taskId, napi_status& status): env_(env), 78 workerEnv_(workerEnv), taskId_(taskId) 79 { 80 status = napi_open_handle_scope(env_, &scope_); 81 } ~CallbackScope()82 ~CallbackScope() 83 { 84 TaskManager::GetInstance().DecreaseRefCount(env_, taskId_); 85 if (workerEnv_ != nullptr) { 86 auto workerEngine = reinterpret_cast<NativeEngine*>(workerEnv_); 87 workerEngine->DecreaseListeningCounter(); 88 } 89 90 if (scope_ != nullptr) { 91 napi_close_handle_scope(env_, scope_); 92 } 93 } 94 private: 95 napi_env env_; 96 napi_env workerEnv_; 97 uint64_t taskId_; 98 napi_handle_scope scope_ = nullptr; 99 }; 100 } // namespace Commonlibrary::Concurrent::TaskPoolModule 101 #endif // JS_CONCURRENT_MODULE_TASKPOOL_TASKPOOL_H