diff --git a/jsapi/BUILD.gn b/BUILD.gn similarity index 83% rename from jsapi/BUILD.gn rename to BUILD.gn index 2c2fc1cc07ed98652c5c1c1247d0417bb733bc7d..d807ae670ffa641deeb8c2ae65b0ed6e2b9788fc 100644 --- a/jsapi/BUILD.gn +++ b/BUILD.gn @@ -14,15 +14,20 @@ import("//build/ohos.gni") ohos_shared_library("worker") { - include_dirs = [ "//base/compileruntime/js_worker_module/jsapi/worker" ] + include_dirs = [ + "//base/compileruntime/js_worker_module/worker", + "//base/compileruntime/js_worker_module/helper", + "//base/compileruntime/js_worker_module/plugin" + ] sources = [ "worker/message_queue.cpp", "worker/native_module_worker.cpp", "worker/thread.cpp", "worker/worker.cpp", - "worker/worker_helper.cpp", "worker/worker_runner.cpp", + "helper/napi_helper.cpp", + "plugin/timer.cpp" ] deps = [ "//foundation/ace/napi:ace_napi" ] diff --git a/bundle.json b/bundle.json index 213c924608502592988db392967f0ddd08a9158f..a225bf3ea72089da06a9859dc6940ef6ec2c6aa2 100644 --- a/bundle.json +++ b/bundle.json @@ -49,7 +49,7 @@ }, "build": { "sub_component": [ - "//base/compileruntime/js_worker_module/jsapi:jsapi_packages" + "//base/compileruntime/js_worker_module:jsapi_packages" ], "inner_kits": [], "test": [] diff --git a/jsapi/worker/worker_helper.cpp b/helper/napi_helper.cpp similarity index 50% rename from jsapi/worker/worker_helper.cpp rename to helper/napi_helper.cpp index 18001a98ecba03ba1f10a46492547b05e31ac8c5..384ca95cfa09e778166235512c35b8571b51e8c0 100644 --- a/jsapi/worker/worker_helper.cpp +++ b/helper/napi_helper.cpp @@ -1,116 +1,177 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "worker_helper.h" - -#include "native_engine/native_value.h" - -namespace OHOS::CCRuntime::Worker { -const static int32_t MAXCHARLENGTH = 200; - -bool NapiValueHelp::IsString(napi_value value) -{ - auto valNative = reinterpret_cast(value); - return valNative == nullptr ? false : valNative->TypeOf() == NATIVE_STRING; -} - -bool NapiValueHelp::IsArray(napi_value value) -{ - auto valNative = reinterpret_cast(value); - return valNative == nullptr ? false : valNative->IsArray(); -} - -bool NapiValueHelp::IsConstructor(napi_env env, napi_callback_info cbInfo) -{ - napi_value* funcObj = nullptr; - napi_get_new_target(env, cbInfo, funcObj); - return funcObj != nullptr; -} - -size_t NapiValueHelp::GetCallbackInfoArgc(napi_env env, napi_callback_info cbInfo) -{ - size_t argc = 0; - napi_get_cb_info(env, cbInfo, &argc, nullptr, nullptr, nullptr); - return argc; -} - -napi_value NapiValueHelp::GetNamePropertyInParentPort(napi_env env, napi_ref parentPort, const char* name) -{ - napi_value obj = nullptr; - napi_get_reference_value(env, parentPort, &obj); - - napi_value value = nullptr; - napi_get_named_property(env, obj, name, &value); - - return value; -} - -napi_value NapiValueHelp::GetUndefinedValue(napi_env env) -{ - napi_value result = nullptr; - napi_get_undefined(env, &result); - return result; -} - -bool NapiValueHelp::IsCallable(napi_env env, napi_value value) -{ - bool result = false; - napi_is_callable(env, value, &result); - return result; -} - -bool NapiValueHelp::IsCallable(napi_env env, napi_ref value) -{ - napi_value obj = nullptr; - napi_get_reference_value(env, value, &obj); - if (obj == nullptr) { - return false; - } - return IsCallable(env, obj); -} - -void NapiValueHelp::SetNamePropertyInGlobal(napi_env env, const char* name, napi_value value) -{ - napi_value object = nullptr; - napi_get_global(env, &object); - napi_set_named_property(env, object, name, value); -} - -bool NapiValueHelp::IsObject(napi_value value) -{ - auto nativeValue = reinterpret_cast(value); - return nativeValue->TypeOf() == NATIVE_OBJECT; -} - -char* NapiValueHelp::GetString(napi_env env, napi_value value) -{ - size_t bufferSize = 0; - size_t strLength = 0; - napi_get_value_string_utf8(env, value, nullptr, 0, &bufferSize); - if (bufferSize > MAXCHARLENGTH) { - return nullptr; - } - char* buffer = new char[bufferSize + 1] { 0 }; - napi_get_value_string_utf8(env, value, buffer, bufferSize + 1, &strLength); - return buffer; -} - -napi_value NapiValueHelp::GetBooleanValue(napi_env env, bool value) -{ - napi_value result = nullptr; - napi_get_boolean(env, value, &result); - return result; -} -} // namespace OHOS::CCRuntime::Worker \ No newline at end of file +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "base/compileruntime/js_worker_module/helper/napi_helper.h" + +#include "native_engine/native_value.h" + +namespace CompilerRuntime::WorkerModule::Helper { +const static int32_t MAXCHARLENGTH = 200; + +bool NapiHelper::IsString(napi_value value) +{ + auto valNative = reinterpret_cast(value); + return valNative == nullptr ? false : valNative->TypeOf() == NATIVE_STRING; +} + +bool NapiHelper::IsArray(napi_value value) +{ + auto valNative = reinterpret_cast(value); + return valNative == nullptr ? false : valNative->IsArray(); +} + +bool NapiHelper::IsConstructor(napi_env env, napi_callback_info cbInfo) +{ + napi_value* funcObj = nullptr; + napi_get_new_target(env, cbInfo, funcObj); + return funcObj != nullptr; +} + +size_t NapiHelper::GetCallbackInfoArgc(napi_env env, napi_callback_info cbInfo) +{ + size_t argc = 0; + napi_get_cb_info(env, cbInfo, &argc, nullptr, nullptr, nullptr); + return argc; +} + +napi_value NapiHelper::GetNamePropertyInParentPort(napi_env env, napi_ref parentPort, const char* name) +{ + napi_value obj = nullptr; + napi_get_reference_value(env, parentPort, &obj); + + napi_value value = nullptr; + napi_get_named_property(env, obj, name, &value); + + return value; +} + +napi_value NapiHelper::GetUndefinedValue(napi_env env) +{ + napi_value result = nullptr; + napi_get_undefined(env, &result); + return result; +} + +bool NapiHelper::IsCallable(napi_env env, napi_value value) +{ + bool result = false; + napi_is_callable(env, value, &result); + return result; +} + +bool NapiHelper::IsCallable(napi_env env, napi_ref value) +{ + napi_value obj = nullptr; + napi_get_reference_value(env, value, &obj); + if (obj == nullptr) { + return false; + } + return IsCallable(env, obj); +} + +void NapiHelper::SetNamePropertyInGlobal(napi_env env, const char* name, napi_value value) +{ + napi_value object = nullptr; + napi_get_global(env, &object); + napi_set_named_property(env, object, name, value); +} + +bool NapiHelper::IsObject(napi_value value) +{ + auto nativeValue = reinterpret_cast(value); + return nativeValue->TypeOf() == NATIVE_OBJECT; +} + +char* NapiHelper::GetString(napi_env env, napi_value value) +{ + size_t bufferSize = 0; + size_t strLength = 0; + napi_get_value_string_utf8(env, value, nullptr, 0, &bufferSize); + if (bufferSize > MAXCHARLENGTH) { + return nullptr; + } + char* buffer = new char[bufferSize + 1] { 0 }; + napi_get_value_string_utf8(env, value, buffer, bufferSize + 1, &strLength); + return buffer; +} + +napi_value NapiHelper::CreateBooleanValue(napi_env env, bool value) +{ + napi_value result = nullptr; + napi_get_boolean(env, value, &result); + return result; +} + +napi_value NapiHelper::GetGlobalObject(napi_env env) +{ + napi_value object = nullptr; + napi_get_global(env, &object); + return object; +} + +napi_ref NapiHelper::CreateReference(napi_env env, napi_value value, uint32_t refcount) +{ + napi_ref callback = nullptr; + napi_create_reference(env, value, refcount, &callback); + return callback; +} + +napi_value NapiHelper::CreateUint32(napi_env env, uint32_t value) +{ + napi_value result = nullptr; + napi_create_uint32(env, value, &result); + return result; +} + +uv_loop_t* NapiHelper::GetLibUV(napi_env env) +{ + uv_loop_t* loop; + napi_get_uv_event_loop(env, &loop); + return loop; +} + +napi_value NapiHelper::GetReferenceValue(napi_env env, napi_ref ref) +{ + napi_value result = nullptr; + napi_get_reference_value(env, ref, &result); + return result; +} + +void NapiHelper::DeleteReference(napi_env env, napi_ref ref) +{ + napi_delete_reference(env, ref); +} + +napi_value NapiHelper::GetNameProperty(napi_env env, napi_value obj, const char* name) +{ + napi_value result = nullptr; + napi_get_named_property(env, obj, name, &result); + return result; +} + +bool NapiHelper::GetBooleanValue(napi_env env, napi_value value) +{ + bool result = false; + napi_get_value_bool(env, value, &result); + return result; +} + +bool NapiHelper::StrictEqual(napi_env env, napi_value value, napi_value cmpValue) +{ + bool isEqual = false; + napi_strict_equals(env, value, cmpValue, &isEqual); + return isEqual; +} +} // namespace CompilerRuntime::WorkerModule::Helper \ No newline at end of file diff --git a/helper/napi_helper.h b/helper/napi_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..db1c239271ee87bb2440a8d1b654c5b82017c0d4 --- /dev/null +++ b/helper/napi_helper.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JS_WORKER_MODULE_HELPER_NAPI_HELPER_H_ +#define JS_WORKER_MODULE_HELPER_NAPI_HELPER_H_ + +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CompilerRuntime::WorkerModule::Helper { +class NapiHelper { +public: + static bool IsString(napi_value value); + static bool IsArray(napi_value value); + static bool IsConstructor(napi_env env, napi_callback_info cbInfo); + static bool IsCallable(napi_env env, napi_value value); + static bool IsCallable(napi_env env, napi_ref value); + static size_t GetCallbackInfoArgc(napi_env env, napi_callback_info cbInfo); + static napi_value GetNamePropertyInParentPort(napi_env env, napi_ref parentPort, const char* name); + static void SetNamePropertyInGlobal(napi_env env, const char* name, napi_value value); + static napi_value GetUndefinedValue(napi_env env); + static bool IsObject(napi_value value); + static char* GetString(napi_env env, napi_value value); + static napi_value CreateBooleanValue(napi_env env, bool value); + static napi_value GetGlobalObject(napi_env env); + static napi_ref CreateReference(napi_env env, napi_value value, uint32_t initial_refcount); + static napi_value CreateUint32(napi_env env, uint32_t value); + static uv_loop_t* GetLibUV(napi_env env); + static napi_value GetReferenceValue(napi_env env, napi_ref ref); + static void DeleteReference(napi_env env, napi_ref ref); + static napi_value GetNameProperty(napi_env env, napi_value obj, const char* name); + static bool GetBooleanValue(napi_env env, napi_value value); + static bool StrictEqual(napi_env env, napi_value value, napi_value cmpValue); +}; +} // namespace CompilerRuntime::WorkerModule::Helper +#endif // JS_WORKER_MODULE_HELPER_NAPI_HELPER_H_ diff --git a/jsapi/worker/worker_helper.h b/helper/object_helper.h similarity index 60% rename from jsapi/worker/worker_helper.h rename to helper/object_helper.h index 734a5a25e983947544ab99fe06bc537681dc264d..f754863bf4a6414104c47718d9363c5a40fb890f 100644 --- a/jsapi/worker/worker_helper.h +++ b/helper/object_helper.h @@ -1,90 +1,71 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef JSAPI_WORKER_WORKER_HELPER_H_ -#define JSAPI_WORKER_WORKER_HELPER_H_ - -#include "napi/native_api.h" -#include "napi/native_node_api.h" - -namespace OHOS::CCRuntime::Worker { -class DereferenceHelp { -public: - template - static Outer* DereferenceOf(const Inner Outer::*field, const Inner* pointer) - { - if (field != nullptr && pointer != nullptr) { - auto fieldOffset = reinterpret_cast(&(static_cast(0)->*field)); - auto outPointer = reinterpret_cast(reinterpret_cast(pointer) - fieldOffset); - return outPointer; - } - return nullptr; - } -}; - -class NapiValueHelp { -public: - static bool IsString(napi_value value); - static bool IsArray(napi_value value); - static bool IsConstructor(napi_env env, napi_callback_info cbInfo); - static bool IsCallable(napi_env env, napi_value value); - static bool IsCallable(napi_env env, napi_ref value); - static size_t GetCallbackInfoArgc(napi_env env, napi_callback_info cbInfo); - static napi_value GetNamePropertyInParentPort(napi_env env, napi_ref parentPort, const char* name); - static void SetNamePropertyInGlobal(napi_env env, const char* name, napi_value value); - static napi_value GetUndefinedValue(napi_env env); - static bool IsObject(napi_value value); - static char* GetString(napi_env env, napi_value value); - static napi_value GetBooleanValue(napi_env env, bool value); -}; - -class CloseHelp { -public: - template - static void DeletePointer(const T* value, bool isArray) - { - if (value == nullptr) { - return; - } - if (isArray) { - delete[] value; - } else { - delete value; - } - } -}; - -template -class ObjectScope { -public: - ObjectScope(const T* data, bool isArray) : data_(data), isArray_(isArray) {} - ~ObjectScope() - { - if (data_ == nullptr) { - return; - } - if (isArray_) { - delete[] data_; - } else { - delete data_; - } - } - -private: - const T* data_; - bool isArray_; -}; -} // namespace OHOS::CCRuntime::Worker -#endif // JSAPI_WORKER_WORKER_HELPER_H_ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JS_WORKER_MODULE_WORKER_OBJECT_HELPER_H_ +#define JS_WORKER_MODULE_WORKER_OBJECT_HELPER_H_ + +namespace CompilerRuntime::WorkerModule::Helper { +class DereferenceHelp { +public: + template + static Outer* DereferenceOf(const Inner Outer::*field, const Inner* pointer) + { + if (field != nullptr && pointer != nullptr) { + auto fieldOffset = reinterpret_cast(&(static_cast(0)->*field)); + auto outPointer = reinterpret_cast(reinterpret_cast(pointer) - fieldOffset); + return outPointer; + } + return nullptr; + } +}; + +class CloseHelp { +public: + template + static void DeletePointer(const T* value, bool isArray) + { + if (value == nullptr) { + return; + } + if (isArray) { + delete[] value; + } else { + delete value; + } + } +}; + +template +class ObjectScope { +public: + ObjectScope(const T* data, bool isArray) : data_(data), isArray_(isArray) {} + ~ObjectScope() + { + if (data_ == nullptr) { + return; + } + if (isArray_) { + delete[] data_; + } else { + delete data_; + } + } + +private: + const T* data_; + bool isArray_; +}; +} // namespace CompilerRuntime::WorkerModule::Helper +#endif // JS_WORKER_MODULE_WORKER_OBJECT_HELPER_H_ diff --git a/plugin/timer.cpp b/plugin/timer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ab72dc95324cdf0ba3e560691d7f2dfbccd916d --- /dev/null +++ b/plugin/timer.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "base/compileruntime/js_worker_module/plugin/timer.h" + +#include "base/compileruntime/js_worker_module/helper/napi_helper.h" +#include "base/compileruntime/js_worker_module/helper/object_helper.h" +#include "utils/log.h" + +namespace CompilerRuntime::WorkerModule::Plugin { +uint32_t Timer::timeCallbackId = 0; +std::map Timer::timerTable; +std::mutex Timer::timeLock; + +TimerCallbackInfo::~TimerCallbackInfo() +{ + Helper::NapiHelper::DeleteReference(env_, callback_); + for (size_t idx = 0; idx < argc_; idx++) { + Helper::NapiHelper::DeleteReference(env_, argv_[idx]); + } + Helper::CloseHelp::DeletePointer(argv_, true); + + uv_timer_stop(&timeReq_); + uv_close(reinterpret_cast(&timeReq_), nullptr); +} + +bool Timer::RegisterTime(napi_env env) +{ + if (env == nullptr) { + return false; + } + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("setTimeout", SetTimeout), + DECLARE_NAPI_FUNCTION("setInterval", SetInterval), + DECLARE_NAPI_FUNCTION("clearTimeout", ClearTimer), + DECLARE_NAPI_FUNCTION("clearInterval", ClearTimer) + }; + napi_value globalObj = Helper::NapiHelper::GetGlobalObject(env); + napi_status status = napi_define_properties(env, globalObj, sizeof(properties) / sizeof(properties[0]), properties); + return status == napi_ok; +} + +napi_value Timer::SetTimeout(napi_env env, napi_callback_info cbinfo) +{ + return Timer::SetTimeoutInner(env, cbinfo, false); +} + +napi_value Timer::SetInterval(napi_env env, napi_callback_info cbinfo) +{ + return Timer::SetTimeoutInner(env, cbinfo, true); +} + +napi_value Timer::ClearTimer(napi_env env, napi_callback_info cbinfo) +{ + // 1. check args + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); + if (argc <= 0) { + HILOG_WARN("first arg should be number"); + return nullptr; + } + napi_value* argv = new napi_value[argc]; + Helper::ObjectScope scope(argv, true); + napi_value thisVar = nullptr; + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr); + + uint32_t tId; + napi_status status = napi_get_value_uint32(env, argv[0], &tId); + if (status != napi_ok) { + HILOG_WARN("handler should be number"); + return nullptr; + } + auto iter = timerTable.find(tId); + if (iter == timerTable.end()) { + HILOG_INFO("handler not in table"); + return nullptr; + } + TimerCallbackInfo* callbackInfo = iter->second; + timerTable.erase(tId); + Helper::CloseHelp::DeletePointer(callbackInfo, false); + return Helper::NapiHelper::GetUndefinedValue(env); +} + +void Timer::TimerCallback(uv_timer_t* handle) +{ + TimerCallbackInfo* callbackInfo = Helper::DereferenceHelp::DereferenceOf(&TimerCallbackInfo::timeReq_, handle); + if (callbackInfo == nullptr) { + return; + } + napi_value callback = Helper::NapiHelper::GetReferenceValue(callbackInfo->env_, callbackInfo->callback_); + napi_value undefinedValue = Helper::NapiHelper::GetUndefinedValue(callbackInfo->env_); + napi_value callbackResult = nullptr; + napi_value* callbackArgv = new napi_value[callbackInfo->argc_]; + Helper::ObjectScope scope(callbackArgv, true); + for (size_t idx = 0; idx < callbackInfo->argc_; idx++) { + callbackArgv[idx] = Helper::NapiHelper::GetReferenceValue(callbackInfo->env_, callbackInfo->argv_[idx]); + } + napi_call_function(callbackInfo->env_, undefinedValue, callback, + callbackInfo->argc_, callbackArgv, &callbackResult); + if (callbackResult == nullptr) { + HILOG_WARN("call callback error"); + return; + } + if (!callbackInfo->repeat_) { + timerTable.erase(callbackInfo->tId_); + Helper::CloseHelp::DeletePointer(callbackInfo, false); + } else { + uv_timer_again(handle); + } +} + +napi_value Timer::SetTimeoutInner(napi_env env, napi_callback_info cbinfo, bool repeat) +{ + // 1. check args + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); + if (argc <= 0) { + napi_throw_error(env, nullptr, "callback must be a function. received undefined"); + return nullptr; + } + napi_value* argv = new napi_value[argc]; + Helper::ObjectScope scope(argv, true); + napi_value thisVar = nullptr; + napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr); + if (!Helper::NapiHelper::IsCallable(env, argv[0])) { + napi_throw_error(env, nullptr, "callback must be a function."); + return nullptr; + } + uint32_t timeout = 0; + if (argc > 1) { + napi_status status = napi_get_value_uint32(env, argv[1], &timeout); + if (status != napi_ok) { + HILOG_WARN("timeout should be number"); + timeout = 0; + } + } + // 2. get callback args + size_t callbackArgc = argc >= 2 ? argc - 2 : 0; // 2 include callback and timeout + napi_ref* callbackArgv = nullptr; + if (callbackArgc > 0) { + callbackArgv = new napi_ref[callbackArgc]; + for (size_t idx = 0; idx < callbackArgc; idx++) { + callbackArgv[idx] = + Helper::NapiHelper::CreateReference(env, argv[idx + 2], 1); // 2 include callback and timeout + } + } + + // 3. generate time callback id; + uint32_t tId = 0; + { + std::lock_guard lock(timeLock); + tId = timeCallbackId++; + } + // 4. generate time callback info + napi_ref callbackRef = Helper::NapiHelper::CreateReference(env, argv[0], 1); + TimerCallbackInfo* callbackInfo = + new TimerCallbackInfo(env, tId, timeout, callbackRef, repeat, callbackArgc, callbackArgv); + uv_loop_t* loop = Helper::NapiHelper::GetLibUV(env); + uv_timer_init(loop, &callbackInfo->timeReq_); + // 5. push callback info into timerTable + timerTable[tId] = callbackInfo; + + // 6. start timer + uv_timer_start(&callbackInfo->timeReq_, TimerCallback, timeout, timeout > 0 ? timeout : 1); + return Helper::NapiHelper::CreateUint32(env, tId); +} + +void Timer::ClearEnvironmentTimer(napi_env env) +{ + auto iter = timerTable.begin(); + while (iter != timerTable.end()) { + TimerCallbackInfo* callbackInfo = iter->second; + if (callbackInfo->env_ == env) { + iter = timerTable.erase(iter); + Helper::CloseHelp::DeletePointer(callbackInfo, false); + } else { + iter++; + } + } +} +} // namespace CompilerRuntime::WorkerModule::Plugin diff --git a/plugin/timer.h b/plugin/timer.h new file mode 100644 index 0000000000000000000000000000000000000000..f30433a0f1865df4e69d44a83209e1c882215342 --- /dev/null +++ b/plugin/timer.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JS_WORKER_MODULE_PLUGIN_TIMER_H_ +#define JS_WORKER_MODULE_PLUGIN_TIMER_H_ + +#include +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace CompilerRuntime::WorkerModule::Plugin { +struct TimerCallbackInfo { + napi_env env_; + uint32_t tId_; + uint32_t timeout_; + napi_ref callback_; + bool repeat_; + uv_timer_t timeReq_; + size_t argc_; + napi_ref* argv_; + + TimerCallbackInfo(napi_env env, uint32_t tId, uint32_t timeout, napi_ref callback, + bool repeat, size_t argc, napi_ref* argv) + : env_(env), tId_(tId), timeout_(timeout), callback_(callback), + repeat_(repeat), argc_(argc), argv_(argv) + {} + + ~TimerCallbackInfo(); +}; + +class Timer { +public: + Timer() = default; + ~Timer() = default; + static bool RegisterTime(napi_env env); + static void ClearEnvironmentTimer(napi_env env); + +private: + static napi_value SetTimeout(napi_env env, napi_callback_info cbinfo); + static napi_value SetInterval(napi_env env, napi_callback_info cbinfo); + static napi_value ClearTimer(napi_env env, napi_callback_info cbinfo); + static napi_value SetTimeoutInner(napi_env env, napi_callback_info cbinfo, bool repeat); + static void TimerCallback(uv_timer_t* handle); + + static uint32_t timeCallbackId; + static std::map timerTable; + static std::mutex timeLock; +}; +} // namespace CompilerRuntime::WorkerModule::Plugin +#endif // JS_WORKER_MODULE_PLUGIN_TIMER_H_ diff --git a/jsapi/worker/message_queue.cpp b/worker/message_queue.cpp similarity index 87% rename from jsapi/worker/message_queue.cpp rename to worker/message_queue.cpp index b886f8f1b611e5fe13bc66f61e37d333e9c89132..66301a2b88d76c110516c1fb829a95ebb732ec6c 100644 --- a/jsapi/worker/message_queue.cpp +++ b/worker/message_queue.cpp @@ -13,10 +13,10 @@ * limitations under the License. */ -#include "message_queue.h" +#include "base/compileruntime/js_worker_module/worker/message_queue.h" #include "utils/log.h" -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { void MessageQueue::EnQueue(MessageDataType data) { queueLock_.lock(); @@ -57,4 +57,4 @@ void MessageQueue::Clear(napi_env env) } queueLock_.unlock(); } -} // namespace OHOS::CCRuntime::Worker +} // namespace CompilerRuntime::WorkerModule diff --git a/jsapi/worker/message_queue.h b/worker/message_queue.h similarity index 79% rename from jsapi/worker/message_queue.h rename to worker/message_queue.h index 9273b5fc685e1a1dfa60ce7e1cffa96f0188eded..2a99c1b51c9e4c6e1e87cddce76633c6c1cd979f 100644 --- a/jsapi/worker/message_queue.h +++ b/worker/message_queue.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef JSAPI_WORKER_MESSAGE_QUEUE_H_ -#define JSAPI_WORKER_MESSAGE_QUEUE_H_ +#ifndef JS_WORKER_MODULE_WORKER_MESSAGE_QUEUE_H_ +#define JS_WORKER_MODULE_WORKER_MESSAGE_QUEUE_H_ #include #include #include "napi/native_api.h" #include "napi/native_node_api.h" -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { using MessageDataType = napi_value; class MessageQueue final { public: @@ -38,5 +38,5 @@ private: std::mutex queueLock_; std::queue queue_; }; -} // namespace OHOS::CCRuntime::Worker -#endif // JSAPI_WORKER_MESSAGE_QUEUE_H_ +} // namespace CompilerRuntime::WorkerModule +#endif // JS_WORKER_MODULE_WORKER_MESSAGE_QUEUE_H_ diff --git a/jsapi/worker/native_module_worker.cpp b/worker/native_module_worker.cpp similarity index 84% rename from jsapi/worker/native_module_worker.cpp rename to worker/native_module_worker.cpp index a5f2d67c55ad7b084cfb193d2472c083965ed25e..327d215bce868c2696e6fefc5b8db8d2a6b6d24d 100644 --- a/jsapi/worker/native_module_worker.cpp +++ b/worker/native_module_worker.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "worker.h" +#include "base/compileruntime/js_worker_module/worker/worker.h" /* * module define @@ -22,7 +22,7 @@ static napi_module g_workerModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, - .nm_register_func = OHOS::CCRuntime::Worker::Worker::InitWorker, + .nm_register_func = CompilerRuntime::WorkerModule::Worker::InitWorker, .nm_modname = "worker", .nm_priv = reinterpret_cast(0), .reserved = { 0 }, diff --git a/jsapi/worker/thread.cpp b/worker/thread.cpp similarity index 82% rename from jsapi/worker/thread.cpp rename to worker/thread.cpp index b13906f9d90df9b6f602cb57e24fe25d7fedbb42..28432ac36ba3672f10e994c11047cc6275816741 100644 --- a/jsapi/worker/thread.cpp +++ b/worker/thread.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ -#include "thread.h" +#include "base/compileruntime/js_worker_module/worker/thread.h" -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { Thread::Thread() : tId_() {} bool Thread::Start() @@ -26,4 +26,4 @@ bool Thread::Start() }, this); return ret != 0; } -} // namespace OHOS::CCRuntime::Worker \ No newline at end of file +} // namespace CompilerRuntime::WorkerModule \ No newline at end of file diff --git a/jsapi/worker/thread.h b/worker/thread.h similarity index 76% rename from jsapi/worker/thread.h rename to worker/thread.h index 3e5f1c495860fa569cf808ea0f6e2b74d1cee5cb..caf21cf673a6e9227e5c2d65c28d2a9aa8ab761f 100644 --- a/jsapi/worker/thread.h +++ b/worker/thread.h @@ -13,12 +13,12 @@ * limitations under the License. */ -#ifndef JSAPI_WORKER_THREAD_H_ -#define JSAPI_WORKER_THREAD_H_ +#ifndef JS_WORKER_MODULE_WORKER_THREAD_H_ +#define JS_WORKER_MODULE_WORKER_THREAD_H_ #include -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { class Thread { public: Thread(); @@ -34,6 +34,6 @@ public: private: uv_thread_t tId_ {0}; }; -} // namespace OHOS::CCRuntime::Worker +} // namespace CompilerRuntime::WorkerModule -#endif // #define JSAPI_WORKER_THREAD_H_ +#endif // #define JS_WORKER_MODULE_WORKER_THREAD_H_ diff --git a/jsapi/worker/worker.cpp b/worker/worker.cpp similarity index 78% rename from jsapi/worker/worker.cpp rename to worker/worker.cpp index f7a08d24f067ca376235fd12445c7ea89d00f20e..284dba44a724fd0448e01bb6bd1885d835fa38bb 100644 --- a/jsapi/worker/worker.cpp +++ b/worker/worker.cpp @@ -13,9 +13,10 @@ * limitations under the License. */ -#include "worker.h" +#include "base/compileruntime/js_worker_module/worker/worker.h" +#include "base/compileruntime/js_worker_module/plugin/timer.h" -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { const static int MAXWORKERS = 8; static std::list g_workers; static std::mutex g_workersMutex; @@ -27,11 +28,10 @@ Worker::Worker(napi_env env, napi_ref thisVar) void Worker::StartExecuteInThread(napi_env env, const char* script) { // 1. init hostOnMessageSignal_ in host loop - auto engine = reinterpret_cast(env); - uv_loop_t* loop = engine->GetUVLoop(); + uv_loop_t* loop = Helper::NapiHelper::GetLibUV(env); if (loop == nullptr) { napi_throw_error(env, nullptr, "worker::engine loop is null"); - CloseHelp::DeletePointer(script, true); + Helper::CloseHelp::DeletePointer(script, true); return; } uv_async_init(loop, &hostOnMessageSignal_, reinterpret_cast(Worker::HostOnMessage)); @@ -39,7 +39,7 @@ void Worker::StartExecuteInThread(napi_env env, const char* script) // 2. copy the script script_ = std::string(script); - CloseHelp::DeletePointer(script, true); + Helper::CloseHelp::DeletePointer(script, true); // 3. create WorkerRunner to Execute if (!runner_) { @@ -65,14 +65,14 @@ napi_value Worker::CloseWorker(napi_env env, napi_callback_info cbinfo) if (worker != nullptr) { worker->CloseInner(); } - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } void CallWorkCallback(napi_env env, napi_value recv, size_t argc, const napi_value* argv, const char* type) { napi_value callback = nullptr; napi_get_named_property(env, recv, type, &callback); - if (NapiValueHelp::IsCallable(env, callback)) { + if (Helper::NapiHelper::IsCallable(env, callback)) { napi_value callbackResult = nullptr; napi_call_function(env, recv, callback, argc, argv, &callbackResult); } @@ -105,6 +105,8 @@ bool Worker::PrepareForWorkerInstance() return false; } } + // add timer interface + Plugin::Timer::RegisterTime(workerEnv_); HILOG_INFO("worker:: stringContent size is %{public}zu", scriptContent.size()); napi_value execScriptResult = nullptr; napi_run_actor(workerEnv_, scriptContent, workerAmi.c_str(), &execScriptResult); @@ -119,7 +121,7 @@ bool Worker::PrepareForWorkerInstance() if (!name_.empty()) { napi_value nameValue = nullptr; napi_create_string_utf8(workerEnv_, name_.c_str(), name_.length(), &nameValue); - NapiValueHelp::SetNamePropertyInGlobal(workerEnv_, "name", nameValue); + Helper::NapiHelper::SetNamePropertyInGlobal(workerEnv_, "name", nameValue); } return true; } @@ -169,7 +171,7 @@ void Worker::ExecuteInThread(const void* data) { std::lock_guard lock(worker->liveStatusLock_); if (worker->HostIsStop()) { - CloseHelp::DeletePointer(worker, false); + Helper::CloseHelp::DeletePointer(worker, false); return; } napi_env env = worker->GetHostEnv(); @@ -204,7 +206,7 @@ void Worker::ExecuteInThread(const void* data) worker->ReleaseWorkerThreadContent(); std::lock_guard lock(worker->liveStatusLock_); if (worker->HostIsStop()) { - CloseHelp::DeletePointer(worker, false); + Helper::CloseHelp::DeletePointer(worker, false); } else { worker->PublishWorkerOverSignal(); } @@ -212,7 +214,7 @@ void Worker::ExecuteInThread(const void* data) void Worker::HostOnMessage(const uv_async_t* req) { - Worker* worker = DereferenceHelp::DereferenceOf(&Worker::hostOnMessageSignal_, req); + Worker* worker = Helper::DereferenceHelp::DereferenceOf(&Worker::hostOnMessageSignal_, req); if (worker == nullptr) { HILOG_ERROR("worker::worker is null"); return; @@ -226,11 +228,9 @@ void Worker::HostOnErrorInner() HILOG_ERROR("worker:: host thread maybe is over"); return; } - napi_value callback = nullptr; - napi_value obj = nullptr; - napi_get_reference_value(hostEnv_, workerRef_, &obj); - napi_get_named_property(hostEnv_, obj, "onerror", &callback); - bool isCallable = NapiValueHelp::IsCallable(hostEnv_, callback); + napi_value obj = Helper::NapiHelper::GetReferenceValue(hostEnv_, workerRef_); + napi_value callback = Helper::NapiHelper::GetNameProperty(hostEnv_, obj, "onerror"); + bool isCallable = Helper::NapiHelper::IsCallable(hostEnv_, callback); if (!isCallable) { HILOG_ERROR("worker:: worker onerror is not Callable"); return; @@ -251,7 +251,7 @@ void Worker::HostOnErrorInner() void Worker::HostOnError(const uv_async_t* req) { - Worker* worker = DereferenceHelp::DereferenceOf(&Worker::hostOnErrorSignal_, req); + Worker* worker = Helper::DereferenceHelp::DereferenceOf(&Worker::hostOnErrorSignal_, req); if (worker == nullptr) { HILOG_ERROR("worker::worker is null"); return; @@ -262,7 +262,7 @@ void Worker::HostOnError(const uv_async_t* req) void Worker::WorkerOnMessage(const uv_async_t* req) { - Worker* worker = DereferenceHelp::DereferenceOf(&Worker::workerOnMessageSignal_, req); + Worker* worker = Helper::DereferenceHelp::DereferenceOf(&Worker::workerOnMessageSignal_, req); if (worker == nullptr) { HILOG_ERROR("worker::worker is null"); return; @@ -276,7 +276,7 @@ void Worker::CloseHostCallback() const napi_create_int32(hostEnv_, 1, &exitValue); napi_value argv[1] = { exitValue }; CallHostFunction(1, argv, "onexit"); - CloseHelp::DeletePointer(this, false); + Helper::CloseHelp::DeletePointer(this, false); } void Worker::HandleEventListeners(napi_env env, napi_value recv, size_t argc, const napi_value* argv, const char* type) @@ -292,13 +292,12 @@ void Worker::HandleEventListeners(napi_env env, napi_value recv, size_t argc, co std::list::iterator it = listeners.begin(); while (it != listeners.end()) { WorkerListener* data = *it++; - napi_value callbackObj = nullptr; - napi_get_reference_value(env, data->callback_, &callbackObj); + napi_value callbackObj = Helper::NapiHelper::GetReferenceValue(env, data->callback_); napi_value callbackResult = nullptr; napi_call_function(env, recv, callbackObj, argc, argv, &callbackResult); if (!data->NextIsAvailable()) { listeners.remove(data); - CloseHelp::DeletePointer(data, false); + Helper::CloseHelp::DeletePointer(data, false); } } } @@ -309,11 +308,9 @@ void Worker::HostOnMessageInner() HILOG_ERROR("worker:: host thread maybe is over"); return; } - napi_value callback = nullptr; - napi_value obj = nullptr; - napi_get_reference_value(hostEnv_, workerRef_, &obj); - napi_get_named_property(hostEnv_, obj, "onmessage", &callback); - bool isCallable = NapiValueHelp::IsCallable(hostEnv_, callback); + napi_value obj = Helper::NapiHelper::GetReferenceValue(hostEnv_, workerRef_); + napi_value callback = Helper::NapiHelper::GetNameProperty(hostEnv_, obj, "onmessage"); + bool isCallable = Helper::NapiHelper::IsCallable(hostEnv_, callback); MessageDataType data = nullptr; while (hostMessageQueue_.DeQueue(&data)) { @@ -355,6 +352,7 @@ void Worker::TerminateWorker() CloseWorkerCallback(); uv_loop_t* loop = GetWorkerLoop(); if (loop != nullptr) { + Plugin::Timer::ClearEnvironmentTimer(workerEnv_); uv_stop(loop); } UpdateWorkerState(TERMINATED); @@ -378,7 +376,7 @@ void Worker::HandleException() if (hostEnv_ != nullptr) { napi_value data = nullptr; - napi_serialize(workerEnv_, exception, NapiValueHelp::GetUndefinedValue(workerEnv_), &data); + napi_serialize(workerEnv_, exception, Helper::NapiHelper::GetUndefinedValue(workerEnv_), &data); { std::lock_guard lock(liveStatusLock_); if (!HostIsStop()) { @@ -427,8 +425,7 @@ void Worker::HostOnMessageErrorInner() HILOG_ERROR("worker:: host thread maybe is over"); return; } - napi_value obj = nullptr; - napi_get_reference_value(hostEnv_, workerRef_, &obj); + napi_value obj = Helper::NapiHelper::GetReferenceValue(hostEnv_, workerRef_); CallHostFunction(0, nullptr, "onmessageerror"); // handle listeners HandleEventListeners(hostEnv_, obj, 0, nullptr, "messageerror"); @@ -441,13 +438,13 @@ void Worker::WorkerOnMessageErrorInner() napi_value Worker::PostMessage(napi_env env, napi_callback_info cbinfo) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < 1) { napi_throw_error(env, nullptr, "Worker param count must be more than 1 with postMessage"); return nullptr; } napi_value* argv = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(argv, true); + Helper::ObjectScope scope(argv, true); napi_value thisVar = nullptr; napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr); Worker* worker = nullptr; @@ -466,31 +463,31 @@ napi_value Worker::PostMessage(napi_env env, napi_callback_info cbinfo) napi_value data = nullptr; napi_status serializeStatus = napi_ok; if (argc >= WORKERPARAMNUM) { - if (!NapiValueHelp::IsArray(argv[1])) { + if (!Helper::NapiHelper::IsArray(argv[1])) { napi_throw_error(env, nullptr, "Transfer list must be an Array"); return nullptr; } serializeStatus = napi_serialize(env, argv[0], argv[1], &data); } else { - serializeStatus = napi_serialize(env, argv[0], NapiValueHelp::GetUndefinedValue(env), &data); + serializeStatus = napi_serialize(env, argv[0], Helper::NapiHelper::GetUndefinedValue(env), &data); } if (serializeStatus != napi_ok || data == nullptr) { worker->HostOnMessageErrorInner(); return nullptr; } worker->PostMessageInner(data); - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } napi_value Worker::PostMessageToHost(napi_env env, napi_callback_info cbinfo) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < 1) { napi_throw_error(env, nullptr, "Worker param count must be more than 1 with new"); return nullptr; } napi_value* argv = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(argv, true); + Helper::ObjectScope scope(argv, true); Worker* worker = nullptr; napi_get_cb_info(env, cbinfo, &argc, argv, nullptr, reinterpret_cast(&worker)); @@ -508,13 +505,13 @@ napi_value Worker::PostMessageToHost(napi_env env, napi_callback_info cbinfo) napi_value data = nullptr; napi_status serializeStatus = napi_ok; if (argc >= WORKERPARAMNUM) { - if (!NapiValueHelp::IsArray(argv[1])) { + if (!Helper::NapiHelper::IsArray(argv[1])) { napi_throw_error(env, nullptr, "Transfer list must be an Array"); return nullptr; } serializeStatus = napi_serialize(env, argv[0], argv[1], &data); } else { - serializeStatus = napi_serialize(env, argv[0], NapiValueHelp::GetUndefinedValue(env), &data); + serializeStatus = napi_serialize(env, argv[0], Helper::NapiHelper::GetUndefinedValue(env), &data); } if (serializeStatus != napi_ok || data == nullptr) { @@ -522,7 +519,7 @@ napi_value Worker::PostMessageToHost(napi_env env, napi_callback_info cbinfo) return nullptr; } worker->PostMessageToHostInner(data); - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } void Worker::PostMessageToHostInner(MessageDataType data) @@ -563,7 +560,7 @@ napi_value Worker::Terminate(napi_env env, napi_callback_info cbinfo) return nullptr; } worker->TerminateInner(); - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } void Worker::TerminateInner() @@ -605,7 +602,7 @@ napi_value Worker::CancelTask(napi_env env, napi_callback_info cbinfo) if (!worker->ClearWorkerTasks()) { HILOG_ERROR("worker:: clear worker task error"); } - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } napi_value Worker::ParentPortCancelTask(napi_env env, napi_callback_info cbinfo) @@ -625,13 +622,13 @@ napi_value Worker::ParentPortCancelTask(napi_env env, napi_callback_info cbinfo) if (!worker->ClearWorkerTasks()) { HILOG_ERROR("worker:: clear worker task error"); } - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } napi_value Worker::WorkerConstructor(napi_env env, napi_callback_info cbinfo) { // check argv count - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < 1) { napi_throw_error(env, nullptr, "Worker param count must be more than 1 with new"); return nullptr; @@ -641,9 +638,9 @@ napi_value Worker::WorkerConstructor(napi_env env, napi_callback_info cbinfo) napi_value thisVar = nullptr; void* data = nullptr; napi_value* args = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(args, true); + Helper::ObjectScope scope(args, true); napi_get_cb_info(env, cbinfo, &argc, args, &thisVar, &data); - if (!NapiValueHelp::IsString(args[0])) { + if (!Helper::NapiHelper::IsString(args[0])) { napi_throw_error(env, nullptr, "Worker 1st param must be string with new"); return nullptr; } @@ -664,41 +661,39 @@ napi_value Worker::WorkerConstructor(napi_env env, napi_callback_info cbinfo) g_workers.push_back(worker); } - if (argc > 1 && NapiValueHelp::IsObject(args[1])) { - napi_value nameValue = nullptr; - napi_get_named_property(env, args[1], "name", &nameValue); - if (NapiValueHelp::IsString(nameValue)) { - char* nameStr = NapiValueHelp::GetString(env, nameValue); + if (argc > 1 && Helper::NapiHelper::IsObject(args[1])) { + napi_value nameValue = Helper::NapiHelper::GetNameProperty(env, args[1], "name"); + if (Helper::NapiHelper::IsString(nameValue)) { + char* nameStr = Helper::NapiHelper::GetString(env, nameValue); if (nameStr == nullptr) { napi_throw_error(env, nullptr, "worker name create error, please check."); return nullptr; } worker->name_ = std::string(nameStr); - CloseHelp::DeletePointer(nameStr, true); + Helper::CloseHelp::DeletePointer(nameStr, true); } - napi_value typeValue = nullptr; - napi_get_named_property(env, args[1], "type", &typeValue); - if (NapiValueHelp::IsString(typeValue)) { - char* typeStr = NapiValueHelp::GetString(env, typeValue); + napi_value typeValue = Helper::NapiHelper::GetNameProperty(env, args[1], "type"); + if (Helper::NapiHelper::IsString(typeValue)) { + char* typeStr = Helper::NapiHelper::GetString(env, typeValue); if (typeStr == nullptr) { napi_throw_error(env, nullptr, "worker type create error, please check."); return nullptr; } if (strcmp("classic", typeStr) == 0) { worker->SetScriptMode(CLASSIC); - CloseHelp::DeletePointer(typeStr, true); + Helper::CloseHelp::DeletePointer(typeStr, true); } else { napi_throw_error(env, nullptr, "unsupport module"); - CloseHelp::DeletePointer(typeStr, true); - CloseHelp::DeletePointer(worker, false); + Helper::CloseHelp::DeletePointer(typeStr, true); + Helper::CloseHelp::DeletePointer(worker, false); return nullptr; } } } // 3. execute in thread - char* script = NapiValueHelp::GetString(env, args[0]); + char* script = Helper::NapiHelper::GetString(env, args[0]); if (script == nullptr) { napi_throw_error(env, nullptr, "worker script create error, please check."); return nullptr; @@ -733,7 +728,7 @@ napi_value Worker::WorkerConstructor(napi_env env, napi_callback_info cbinfo) napi_value Worker::AddListener(napi_env env, napi_callback_info cbinfo, ListenerMode mode) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < WORKERPARAMNUM) { napi_throw_error(env, nullptr, "Worker param count must be more than WORKPARAMNUM with on"); return nullptr; @@ -742,13 +737,13 @@ napi_value Worker::AddListener(napi_env env, napi_callback_info cbinfo, Listener napi_value thisVar = nullptr; void* data = nullptr; napi_value* args = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(args, true); + Helper::ObjectScope scope(args, true); napi_get_cb_info(env, cbinfo, &argc, args, &thisVar, &data); - if (!NapiValueHelp::IsString(args[0])) { + if (!Helper::NapiHelper::IsString(args[0])) { napi_throw_error(env, nullptr, "Worker 1st param must be string with on"); return nullptr; } - if (!NapiValueHelp::IsCallable(env, args[1])) { + if (!Helper::NapiHelper::IsCallable(env, args[1])) { napi_throw_error(env, nullptr, "Worker 2st param must be callable with on"); return nullptr; } @@ -759,42 +754,34 @@ napi_value Worker::AddListener(napi_env env, napi_callback_info cbinfo, Listener return nullptr; } - auto listener = new WorkerListener(worker, mode); + napi_ref callback = Helper::NapiHelper::CreateReference(env, args[1], 1); + auto listener = new WorkerListener(env, callback, mode); if (mode == ONCE && argc > WORKERPARAMNUM) { - if (NapiValueHelp::IsObject(args[WORKERPARAMNUM])) { - napi_value onceValue = nullptr; - napi_get_named_property(env, args[WORKERPARAMNUM], "once", &onceValue); - bool isOnce = false; - napi_get_value_bool(env, onceValue, &isOnce); + if (Helper::NapiHelper::IsObject(args[WORKERPARAMNUM])) { + napi_value onceValue = Helper::NapiHelper::GetNameProperty(env, args[WORKERPARAMNUM], "once"); + bool isOnce = Helper::NapiHelper::GetBooleanValue(env, onceValue); if (!isOnce) { listener->SetMode(PERMANENT); } } } - listener->SetCallable(env, args[1]); - char* typeStr = NapiValueHelp::GetString(env, args[0]); + char* typeStr = Helper::NapiHelper::GetString(env, args[0]); if (typeStr == nullptr) { - CloseHelp::DeletePointer(listener, false); + Helper::CloseHelp::DeletePointer(listener, false); napi_throw_error(env, nullptr, "worker listener type create error, please check."); return nullptr; } worker->AddListenerInner(env, typeStr, listener); - CloseHelp::DeletePointer(typeStr, true); - return NapiValueHelp::GetUndefinedValue(env); + Helper::CloseHelp::DeletePointer(typeStr, true); + return Helper::NapiHelper::GetUndefinedValue(env); } bool Worker::WorkerListener::operator==(const WorkerListener& listener) const { - if (listener.worker_ == nullptr) { - return false; - } - napi_env env = listener.worker_->GetHostEnv(); - napi_value obj = nullptr; - napi_get_reference_value(env, listener.callback_, &obj); - - napi_value compareObj = nullptr; - napi_get_reference_value(env, callback_, &compareObj); - return obj == compareObj; + napi_value obj = Helper::NapiHelper::GetReferenceValue(listener.env_, listener.callback_); + napi_value compareObj = Helper::NapiHelper::GetReferenceValue(env_, callback_); + // the env of listener and cmp listener must be same env because of Synchronization method + return Helper::NapiHelper::StrictEqual(env_, compareObj, obj); } void Worker::AddListenerInner(napi_env env, const char* type, const WorkerListener* listener) @@ -828,12 +815,12 @@ void Worker::RemoveListenerInner(napi_env env, const char* type, napi_ref callba std::list::iterator it = std::find_if(listenerList.begin(), listenerList.end(), Worker::FindWorkerListener(env, callback)); if (it != listenerList.end()) { - CloseHelp::DeletePointer(*it, false); + Helper::CloseHelp::DeletePointer(*it, false); listenerList.erase(it); } } else { for (auto it = listenerList.begin(); it != listenerList.end(); it++) { - CloseHelp::DeletePointer(*it, false); + Helper::CloseHelp::DeletePointer(*it, false); } eventListeners_.erase(typestr); } @@ -851,7 +838,7 @@ napi_value Worker::Once(napi_env env, napi_callback_info cbinfo) napi_value Worker::RemoveListener(napi_env env, napi_callback_info cbinfo) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < 1) { napi_throw_error(env, nullptr, "Worker param count must be more than 2 with on"); return nullptr; @@ -860,9 +847,9 @@ napi_value Worker::RemoveListener(napi_env env, napi_callback_info cbinfo) napi_value thisVar = nullptr; void* data = nullptr; napi_value* args = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(args, true); + Helper::ObjectScope scope(args, true); napi_get_cb_info(env, cbinfo, &argc, args, &thisVar, &data); - if (!NapiValueHelp::IsString(args[0])) { + if (!Helper::NapiHelper::IsString(args[0])) { napi_throw_error(env, nullptr, "Worker 1st param must be string with on"); return nullptr; } @@ -874,24 +861,25 @@ napi_value Worker::RemoveListener(napi_env env, napi_callback_info cbinfo) return nullptr; } - napi_ref callback = nullptr; - if (argc > 1 && !NapiValueHelp::IsCallable(env, args[1])) { + if (argc > 1 && !Helper::NapiHelper::IsCallable(env, args[1])) { napi_throw_error(env, nullptr, "Worker 2st param must be callable with on"); return nullptr; } - if (argc > 1 && NapiValueHelp::IsCallable(env, args[1])) { - napi_create_reference(env, args[1], 1, &callback); - } - char* typeStr = NapiValueHelp::GetString(env, args[0]); + char* typeStr = Helper::NapiHelper::GetString(env, args[0]); if (typeStr == nullptr) { napi_throw_error(env, nullptr, "worker listener type create error, please check."); return nullptr; } + + napi_ref callback = nullptr; + if (argc > 1 && Helper::NapiHelper::IsCallable(env, args[1])) { + napi_create_reference(env, args[1], 1, &callback); + } worker->RemoveListenerInner(env, typeStr, callback); - CloseHelp::DeletePointer(typeStr, true); - napi_delete_reference(env, callback); - return NapiValueHelp::GetUndefinedValue(env); + Helper::CloseHelp::DeletePointer(typeStr, true); + Helper::NapiHelper::DeleteReference(env, callback); + return Helper::NapiHelper::GetUndefinedValue(env); } napi_value Worker::Off(napi_env env, napi_callback_info cbinfo) @@ -906,46 +894,44 @@ napi_value Worker::AddEventListener(napi_env env, napi_callback_info cbinfo) napi_value Worker::DispatchEvent(napi_env env, napi_callback_info cbinfo) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < 1) { napi_throw_error(env, nullptr, "worker:: DispatchEvent param count must be more than 1"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } // check 1st param is string napi_value thisVar = nullptr; void* data = nullptr; napi_value* args = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(args, true); + Helper::ObjectScope scope(args, true); napi_get_cb_info(env, cbinfo, &argc, args, &thisVar, &data); - if (!NapiValueHelp::IsObject(args[0])) { + if (!Helper::NapiHelper::IsObject(args[0])) { napi_throw_error(env, nullptr, "worker DispatchEvent 1st param must be Event"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } Worker* worker = nullptr; napi_unwrap(env, thisVar, reinterpret_cast(&worker)); if (worker == nullptr) { HILOG_ERROR("worker:: worker is nullptr when DispatchEvent, maybe worker is terminated"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } - napi_value typeValue = nullptr; - napi_get_named_property(env, args[0], "type", &typeValue); - if (!NapiValueHelp::IsString(typeValue)) { + napi_value typeValue = Helper::NapiHelper::GetNameProperty(env, args[0], "type"); + if (!Helper::NapiHelper::IsString(typeValue)) { napi_throw_error(env, nullptr, "worker event type must be string"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } - napi_value obj = nullptr; - napi_get_reference_value(env, worker->workerRef_, &obj); + napi_value obj = Helper::NapiHelper::GetReferenceValue(env, worker->workerRef_); napi_value argv[1] = { args[0] }; - char* typeStr = NapiValueHelp::GetString(env, typeValue); + char* typeStr = Helper::NapiHelper::GetString(env, typeValue); if (typeStr == nullptr) { napi_throw_error(env, nullptr, "worker listener type create error, please check."); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } if (strcmp(typeStr, "error") == 0) { CallWorkCallback(env, obj, 1, argv, "onerror"); @@ -957,8 +943,8 @@ napi_value Worker::DispatchEvent(napi_env env, napi_callback_info cbinfo) worker->HandleEventListeners(env, obj, 1, argv, typeStr); - CloseHelp::DeletePointer(typeStr, true); - return NapiValueHelp::GetBooleanValue(env, true); + Helper::CloseHelp::DeletePointer(typeStr, true); + return Helper::NapiHelper::CreateBooleanValue(env, true); } napi_value Worker::RemoveEventListener(napi_env env, napi_callback_info cbinfo) @@ -972,7 +958,7 @@ void Worker::RemoveAllListenerInner() std::list& listeners = iter->second; for (auto item = listeners.begin(); item != listeners.end(); item++) { WorkerListener* listener = *item; - CloseHelp::DeletePointer(listener, false); + Helper::CloseHelp::DeletePointer(listener, false); } } eventListeners_.clear(); @@ -990,12 +976,12 @@ napi_value Worker::RemoveAllListener(napi_env env, napi_callback_info cbinfo) } worker->RemoveAllListenerInner(); - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } napi_value Worker::InitWorker(napi_env env, napi_value exports) { - NativeEngine *engine = reinterpret_cast(env); + NativeEngine* engine = reinterpret_cast(env); const char className[] = "Worker"; napi_property_descriptor properties[] = { DECLARE_NAPI_FUNCTION("postMessage", PostMessage), @@ -1015,7 +1001,7 @@ napi_value Worker::InitWorker(napi_env env, napi_value exports) napi_set_named_property(env, exports, "Worker", workerClazz); if (!engine->IsMainThread()) { - Worker *worker = nullptr; + Worker* worker = nullptr; for (auto item = g_workers.begin(); item != g_workers.end(); item++) { if ((*item)->IsSameWorkerEnv(env)) { worker = *item; @@ -1065,13 +1051,13 @@ bool Worker::CallWorkerFunction(size_t argc, const napi_value* argv, const char* if (workerEnv_ == nullptr) { return false; } - napi_value callback = NapiValueHelp::GetNamePropertyInParentPort(workerEnv_, parentPort_, methodName); - bool isCallable = NapiValueHelp::IsCallable(workerEnv_, callback); + napi_value callback = Helper::NapiHelper::GetNamePropertyInParentPort(workerEnv_, parentPort_, methodName); + bool isCallable = Helper::NapiHelper::IsCallable(workerEnv_, callback); if (!isCallable) { HILOG_ERROR("worker:: WorkerGlobalScope %{public}s is not Callable", methodName); return false; } - napi_value undefinedValue = NapiValueHelp::GetUndefinedValue(workerEnv_); + napi_value undefinedValue = Helper::NapiHelper::GetUndefinedValue(workerEnv_); napi_value callbackResult = nullptr; napi_call_function(workerEnv_, undefinedValue, callback, argc, argv, &callbackResult); if (tryCatch && callbackResult == nullptr) { @@ -1104,11 +1090,9 @@ void Worker::CallHostFunction(size_t argc, const napi_value* argv, const char* m HILOG_ERROR("worker:: host thread maybe is over"); return; } - napi_value callback = nullptr; - napi_value obj = nullptr; - napi_get_reference_value(hostEnv_, workerRef_, &obj); - napi_get_named_property(hostEnv_, obj, methodName, &callback); - bool isCallable = NapiValueHelp::IsCallable(hostEnv_, callback); + napi_value obj = Helper::NapiHelper::GetReferenceValue(hostEnv_, workerRef_); + napi_value callback = Helper::NapiHelper::GetNameProperty(hostEnv_, obj, methodName); + bool isCallable = Helper::NapiHelper::IsCallable(hostEnv_, callback); if (!isCallable) { HILOG_ERROR("worker:: worker %{public}s is not Callable", methodName); return; @@ -1131,7 +1115,7 @@ void Worker::ReleaseWorkerThreadContent() ParentPortRemoveAllListenerInner(); // 2. delete worker's parentPort - napi_delete_reference(workerEnv_, parentPort_); + Helper::NapiHelper::DeleteReference(workerEnv_, parentPort_); parentPort_ = nullptr; // 3. clear message send to worker thread @@ -1139,7 +1123,7 @@ void Worker::ReleaseWorkerThreadContent() // 4. delete NativeEngine created in worker thread auto workerEngine = reinterpret_cast(workerEnv_); workerEngine->CloseAsyncWork(); - CloseHelp::DeletePointer(reinterpret_cast(workerEnv_), false); + Helper::CloseHelp::DeletePointer(reinterpret_cast(workerEnv_), false); workerEnv_ = nullptr; } @@ -1151,12 +1135,11 @@ void Worker::ReleaseHostThreadContent() errorQueue_.Clear(hostEnv_); if (!HostIsStop()) { // 3. set thisVar's nativepointer be null - napi_value thisVar = nullptr; - napi_get_reference_value(hostEnv_, workerRef_, &thisVar); + napi_value thisVar = Helper::NapiHelper::GetReferenceValue(hostEnv_, workerRef_); Worker* worker = nullptr; napi_remove_wrap(hostEnv_, thisVar, reinterpret_cast(&worker)); // 4. set workerRef_ be null - napi_delete_reference(hostEnv_, workerRef_); + Helper::NapiHelper::DeleteReference(hostEnv_, workerRef_); } hostEnv_ = nullptr; workerRef_ = nullptr; @@ -1164,23 +1147,23 @@ void Worker::ReleaseHostThreadContent() napi_value Worker::ParentPortAddEventListener(napi_env env, napi_callback_info cbinfo) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < WORKERPARAMNUM) { napi_throw_error(env, nullptr, "Worker param count must be more than WORKPARAMNUM with on"); return nullptr; } napi_value* args = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(args, true); + Helper::ObjectScope scope(args, true); Worker* worker = nullptr; napi_get_cb_info(env, cbinfo, &argc, args, nullptr, reinterpret_cast(&worker)); - if (!NapiValueHelp::IsString(args[0])) { + if (!Helper::NapiHelper::IsString(args[0])) { napi_throw_error(env, nullptr, "Worker 1st param must be string with on"); return nullptr; } - if (!NapiValueHelp::IsCallable(env, args[1])) { + if (!Helper::NapiHelper::IsCallable(env, args[1])) { napi_throw_error(env, nullptr, "Worker 2st param must be callable with on"); return nullptr; } @@ -1196,26 +1179,24 @@ napi_value Worker::ParentPortAddEventListener(napi_env env, napi_callback_info c return nullptr; } - auto listener = new WorkerListener(worker, PERMANENT); - if (argc > WORKERPARAMNUM && NapiValueHelp::IsObject(args[WORKERPARAMNUM])) { - napi_value onceValue = nullptr; - napi_get_named_property(env, args[WORKERPARAMNUM], "once", &onceValue); - bool isOnce = false; - napi_get_value_bool(env, onceValue, &isOnce); + napi_ref callback = Helper::NapiHelper::CreateReference(env, args[1], 1); + auto listener = new WorkerListener(env, callback, PERMANENT); + if (argc > WORKERPARAMNUM && Helper::NapiHelper::IsObject(args[WORKERPARAMNUM])) { + napi_value onceValue = Helper::NapiHelper::GetNameProperty(env, args[WORKERPARAMNUM], "once"); + bool isOnce = Helper::NapiHelper::GetBooleanValue(env, onceValue); if (isOnce) { listener->SetMode(ONCE); } } - listener->SetCallable(env, args[1]); - char* typeStr = NapiValueHelp::GetString(env, args[0]); + char* typeStr = Helper::NapiHelper::GetString(env, args[0]); if (typeStr == nullptr) { - CloseHelp::DeletePointer(listener, false); + Helper::CloseHelp::DeletePointer(listener, false); napi_throw_error(env, nullptr, "worker listener type create error, please check."); return nullptr; } worker->ParentPortAddListenerInner(env, typeStr, listener); - CloseHelp::DeletePointer(typeStr, true); - return NapiValueHelp::GetUndefinedValue(env); + Helper::CloseHelp::DeletePointer(typeStr, true); + return Helper::NapiHelper::GetUndefinedValue(env); } napi_value Worker::ParentPortRemoveAllListener(napi_env env, napi_callback_info cbinfo) @@ -1235,54 +1216,52 @@ napi_value Worker::ParentPortRemoveAllListener(napi_env env, napi_callback_info } worker->ParentPortRemoveAllListenerInner(); - return NapiValueHelp::GetUndefinedValue(env); + return Helper::NapiHelper::GetUndefinedValue(env); } napi_value Worker::ParentPortDispatchEvent(napi_env env, napi_callback_info cbinfo) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < 1) { napi_throw_error(env, nullptr, "worker:: DispatchEvent param count must be more than 1"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } napi_value* args = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(args, true); + Helper::ObjectScope scope(args, true); Worker* worker = nullptr; napi_get_cb_info(env, cbinfo, &argc, args, nullptr, reinterpret_cast(&worker)); - if (!NapiValueHelp::IsObject(args[0])) { + if (!Helper::NapiHelper::IsObject(args[0])) { napi_throw_error(env, nullptr, "worker DispatchEvent 1st param must be Event"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } - napi_value typeValue = nullptr; - napi_get_named_property(env, args[0], "type", &typeValue); - if (!NapiValueHelp::IsString(typeValue)) { + napi_value typeValue = Helper::NapiHelper::GetNameProperty(env, args[0], "type"); + if (!Helper::NapiHelper::IsString(typeValue)) { napi_throw_error(env, nullptr, "worker event type must be string"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } if (worker == nullptr) { HILOG_ERROR("worker:: when post message to host occur worker is nullptr"); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } if (!worker->IsRunning()) { // if worker is not running, don't send any message to host thread HILOG_INFO("worker:: when post message to host occur worker is not in running."); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } napi_value argv[1] = { args[0] }; - char* typeStr = NapiValueHelp::GetString(env, typeValue); + char* typeStr = Helper::NapiHelper::GetString(env, typeValue); if (typeStr == nullptr) { napi_throw_error(env, nullptr, "worker listener type create error, please check."); - return NapiValueHelp::GetBooleanValue(env, false); + return Helper::NapiHelper::CreateBooleanValue(env, false); } - napi_value obj = nullptr; - napi_get_reference_value(env, worker->parentPort_, &obj); + napi_value obj = Helper::NapiHelper::GetReferenceValue(env, worker->parentPort_); if (strcmp(typeStr, "error") == 0) { CallWorkCallback(env, obj, 1, argv, "onerror"); @@ -1294,29 +1273,29 @@ napi_value Worker::ParentPortDispatchEvent(napi_env env, napi_callback_info cbin worker->ParentPortHandleEventListeners(env, obj, 1, argv, typeStr); - CloseHelp::DeletePointer(typeStr, true); - return NapiValueHelp::GetBooleanValue(env, true); + Helper::CloseHelp::DeletePointer(typeStr, true); + return Helper::NapiHelper::CreateBooleanValue(env, true); } napi_value Worker::ParentPortRemoveEventListener(napi_env env, napi_callback_info cbinfo) { - size_t argc = NapiValueHelp::GetCallbackInfoArgc(env, cbinfo); + size_t argc = Helper::NapiHelper::GetCallbackInfoArgc(env, cbinfo); if (argc < 1) { napi_throw_error(env, nullptr, "Worker param count must be more than 2 with on"); return nullptr; } napi_value* args = new napi_value[argc]; - [[maybe_unused]] ObjectScope scope(args, true); + Helper::ObjectScope scope(args, true); Worker* worker = nullptr; napi_get_cb_info(env, cbinfo, &argc, args, nullptr, reinterpret_cast(&worker)); - if (!NapiValueHelp::IsString(args[0])) { + if (!Helper::NapiHelper::IsString(args[0])) { napi_throw_error(env, nullptr, "Worker 1st param must be string with on"); return nullptr; } - if (argc > 1 && !NapiValueHelp::IsCallable(env, args[1])) { + if (argc > 1 && !Helper::NapiHelper::IsCallable(env, args[1])) { napi_throw_error(env, nullptr, "Worker 2st param must be callable with on"); return nullptr; } @@ -1333,19 +1312,19 @@ napi_value Worker::ParentPortRemoveEventListener(napi_env env, napi_callback_inf } napi_ref callback = nullptr; - if (argc > 1 && NapiValueHelp::IsCallable(env, args[1])) { + if (argc > 1 && Helper::NapiHelper::IsCallable(env, args[1])) { napi_create_reference(env, args[1], 1, &callback); } - char* typeStr = NapiValueHelp::GetString(env, args[0]); + char* typeStr = Helper::NapiHelper::GetString(env, args[0]); if (typeStr == nullptr) { napi_throw_error(env, nullptr, "worker listener type create error, please check."); return nullptr; } worker->ParentPortRemoveListenerInner(env, typeStr, callback); - CloseHelp::DeletePointer(typeStr, true); - napi_delete_reference(env, callback); - return NapiValueHelp::GetUndefinedValue(env); + Helper::CloseHelp::DeletePointer(typeStr, true); + Helper::NapiHelper::DeleteReference(env, callback); + return Helper::NapiHelper::GetUndefinedValue(env); } void Worker::ParentPortAddListenerInner(napi_env env, const char* type, const WorkerListener* listener) @@ -1373,7 +1352,7 @@ void Worker::ParentPortRemoveAllListenerInner() std::list& listeners = iter->second; for (auto item = listeners.begin(); item != listeners.end(); item++) { WorkerListener* listener = *item; - CloseHelp::DeletePointer(listener, false); + Helper::CloseHelp::DeletePointer(listener, false); } } parentPortEventListeners_.clear(); @@ -1391,12 +1370,12 @@ void Worker::ParentPortRemoveListenerInner(napi_env env, const char* type, napi_ std::list::iterator it = std::find_if(listenerList.begin(), listenerList.end(), Worker::FindWorkerListener(env, callback)); if (it != listenerList.end()) { - CloseHelp::DeletePointer(*it, false); + Helper::CloseHelp::DeletePointer(*it, false); listenerList.erase(it); } } else { for (auto it = listenerList.begin(); it != listenerList.end(); it++) { - CloseHelp::DeletePointer(*it, false); + Helper::CloseHelp::DeletePointer(*it, false); } parentPortEventListeners_.erase(typestr); } @@ -1416,14 +1395,13 @@ void Worker::ParentPortHandleEventListeners(napi_env env, napi_value recv, std::list::iterator it = listeners.begin(); while (it != listeners.end()) { WorkerListener* data = *it++; - napi_value callbackObj = nullptr; - napi_get_reference_value(env, data->callback_, &callbackObj); + napi_value callbackObj = Helper::NapiHelper::GetReferenceValue(env, data->callback_); napi_value callbackResult = nullptr; napi_call_function(env, recv, callbackObj, argc, argv, &callbackResult); if (!data->NextIsAvailable()) { listeners.remove(data); - CloseHelp::DeletePointer(data, false); + Helper::CloseHelp::DeletePointer(data, false); } } } -} // namespace OHOS::CCRuntime::Worker +} // namespace CompilerRuntime::WorkerModule diff --git a/jsapi/worker/worker.h b/worker/worker.h similarity index 87% rename from jsapi/worker/worker.h rename to worker/worker.h index 08b30f152066e2b31a361eb24b2be6093c5ab97c..f151bc9b450940927e99d098d533639a29fbce55 100644 --- a/jsapi/worker/worker.h +++ b/worker/worker.h @@ -13,22 +13,22 @@ * limitations under the License. */ -#ifndef JSAPI_WORKER_WORKER_H_ -#define JSAPI_WORKER_WORKER_H_ +#ifndef JS_WORKER_MODULE_WORKER_WORKER_H_ +#define JS_WORKER_MODULE_WORKER_WORKER_H_ #include #include #include -#include -#include "message_queue.h" +#include "base/compileruntime/js_worker_module/worker/message_queue.h" +#include "base/compileruntime/js_worker_module/helper/napi_helper.h" +#include "base/compileruntime/js_worker_module/helper/object_helper.h" +#include "base/compileruntime/js_worker_module/worker/worker_runner.h" #include "napi/native_api.h" #include "napi/native_node_api.h" #include "native_engine/native_engine.h" #include "utils/log.h" -#include "worker_helper.h" -#include "worker_runner.h" -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { class Worker { public: static const int8_t WORKERPARAMNUM = 2; @@ -40,16 +40,14 @@ public: enum ScriptMode { CLASSIC, MODULE }; struct WorkerListener { - WorkerListener() : callback_(nullptr), worker_(nullptr), mode_(PERMANENT) {} - - explicit WorkerListener(Worker* worker) : callback_(nullptr), worker_(worker), mode_(PERMANENT) {} - - WorkerListener(Worker* worker, ListenerMode mode) : callback_(nullptr), worker_(worker), mode_(mode) {} + WorkerListener(napi_env env, napi_ref callback, ListenerMode mode) + : env_(env), callback_(callback), mode_(mode) + {} ~WorkerListener() { + Helper::NapiHelper::DeleteReference(env_, callback_); callback_ = nullptr; - worker_ = nullptr; } bool NextIsAvailable() const @@ -57,11 +55,6 @@ public: return mode_ != ONCE; } - void SetCallable(napi_env env, napi_value value) - { - napi_create_reference(env, value, 1, &callback_); - } - void SetMode(ListenerMode mode) { mode_ = mode; @@ -69,8 +62,8 @@ public: bool operator==(const WorkerListener& listener) const; + napi_env env_ {NULL}; napi_ref callback_ {NULL}; - Worker* worker_ {nullptr}; ListenerMode mode_ {PERMANENT}; }; @@ -79,14 +72,10 @@ public: bool operator()(const WorkerListener* listener) const { - napi_value compareObj = nullptr; - napi_get_reference_value(env_, listener->callback_, &compareObj); - - napi_value obj = nullptr; - napi_get_reference_value(env_, ref_, &obj); - bool isEqual = false; - napi_strict_equals(env_, compareObj, obj, &isEqual); - return isEqual; + napi_value compareObj = Helper::NapiHelper::GetReferenceValue(env_, listener->callback_); + napi_value obj = Helper::NapiHelper::GetReferenceValue(env_, ref_); + // the env of listener and cmp listener must be same env because of Synchronization method + return Helper::NapiHelper::StrictEqual(env_, compareObj, obj); } napi_env env_ {nullptr}; @@ -334,7 +323,7 @@ public: uv_loop_t* GetWorkerLoop() const { if (workerEnv_ != nullptr) { - return reinterpret_cast(workerEnv_)->GetUVLoop(); + return Helper::NapiHelper::GetLibUV(workerEnv_); } return nullptr; } @@ -375,9 +364,8 @@ public: void Loop() { - if (workerEnv_ != nullptr) { - reinterpret_cast(workerEnv_)->Loop(LOOP_DEFAULT); - } + uv_loop_t* loop = GetWorkerLoop(); + uv_run(loop, UV_RUN_DEFAULT); } private: @@ -452,5 +440,5 @@ private: std::recursive_mutex liveStatusLock_ {}; }; -} // namespace OHOS::CCRuntime::Worker -#endif // JSAPI_WORKER_WORKER_H_ +} // namespace CompilerRuntime::WorkerModule +#endif // JS_WORKER_MODULE_WORKER_WORKER_H_ diff --git a/jsapi/worker/worker_runner.cpp b/worker/worker_runner.cpp similarity index 78% rename from jsapi/worker/worker_runner.cpp rename to worker/worker_runner.cpp index 08545b417e454620f2fc20d30a47062f61e802f4..3b535fd0e7835838148596655e6d62f3b5d086e6 100644 --- a/jsapi/worker/worker_runner.cpp +++ b/worker/worker_runner.cpp @@ -13,18 +13,16 @@ * limitations under the License. */ -#include "worker_runner.h" +#include "base/compileruntime/js_worker_module/worker/worker_runner.h" -#include -#include -#include "worker_helper.h" +#include "base/compileruntime/js_worker_module/helper/object_helper.h" -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { WorkerRunner::WorkerRunner(WorkerStartCallback callback) : callback_(callback), selfThreadId_(uv_thread_self()) {} WorkerRunner::~WorkerRunner() { - CloseHelp::DeletePointer(workerInnerRunner_, false); + Helper::CloseHelp::DeletePointer(workerInnerRunner_, false); } void WorkerRunner::WorkerInnerRunner::Run() @@ -48,4 +46,4 @@ bool WorkerRunner::Execute() workerInnerRunner_ = new WorkerInnerRunner(this); return workerInnerRunner_->Start(); } -} // namespace OHOS::CCRuntime::Worker +} // namespace CompilerRuntime::WorkerModule diff --git a/jsapi/worker/worker_runner.h b/worker/worker_runner.h similarity index 80% rename from jsapi/worker/worker_runner.h rename to worker/worker_runner.h index 027b166129688373da892734891e225bc2249abe..ca3dbfffcc27b99d7af017305f326a02d44b46b1 100644 --- a/jsapi/worker/worker_runner.h +++ b/worker/worker_runner.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef JSAPI_WORKER_WORKER_RUNNER_H_ -#define JSAPI_WORKER_WORKER_RUNNER_H_ +#ifndef JS_WORKER_MODULE_WORKER_WORKER_RUNNER_H_ +#define JS_WORKER_MODULE_WORKER_WORKER_RUNNER_H_ #include #include "native_engine/native_engine.h" -#include "thread.h" +#include "base/compileruntime/js_worker_module/worker/thread.h" -namespace OHOS::CCRuntime::Worker { +namespace CompilerRuntime::WorkerModule { struct WorkerStartCallback { using CallbackFunction = std::function; @@ -58,5 +58,5 @@ private: WorkerStartCallback callback_; uv_thread_t selfThreadId_ {0}; }; -} // namespace OHOS::CCRuntime::Worker -#endif // JSAPI_WORKER_WORKER_RUNNER_H_ +} // namespace CompilerRuntime::WorkerModule +#endif // JS_WORKER_MODULE_WORKER_WORKER_RUNNER_H_