add Timer Interface for worker

execute polling operation and delay operation in the worker Without
waking up the system,add timer related interfaces,
setTimeout, setinterval, cleartimeout, clearinterval in worker
initialize

issue: https://gitee.com/openharmony/js_worker_module/issues/I51DAA

Signed-off-by: y00576111 <yaojian16@huawei.com>
Change-Id: I7089854c7f557c3f1d9f906854a2dad682e68400
This commit is contained in:
y00576111
2022-04-06 21:49:23 +08:00
committed by wangzhaoyong
parent 10422f5c3e
commit 1459ce5be1
16 changed files with 769 additions and 455 deletions
+7 -2
View File
@@ -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" ]
+1 -1
View File
@@ -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": []
@@ -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<NativeValue*>(value);
return valNative == nullptr ? false : valNative->TypeOf() == NATIVE_STRING;
}
bool NapiValueHelp::IsArray(napi_value value)
{
auto valNative = reinterpret_cast<NativeValue*>(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<NativeValue*>(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
/*
* 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<NativeValue*>(value);
return valNative == nullptr ? false : valNative->TypeOf() == NATIVE_STRING;
}
bool NapiHelper::IsArray(napi_value value)
{
auto valNative = reinterpret_cast<NativeValue*>(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<NativeValue*>(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
+49
View File
@@ -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 <uv.h>
#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_
@@ -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<typename Inner, typename Outer>
static Outer* DereferenceOf(const Inner Outer::*field, const Inner* pointer)
{
if (field != nullptr && pointer != nullptr) {
auto fieldOffset = reinterpret_cast<uintptr_t>(&(static_cast<Outer*>(0)->*field));
auto outPointer = reinterpret_cast<Outer*>(reinterpret_cast<uintptr_t>(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<typename T>
static void DeletePointer(const T* value, bool isArray)
{
if (value == nullptr) {
return;
}
if (isArray) {
delete[] value;
} else {
delete value;
}
}
};
template<typename T>
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<typename Inner, typename Outer>
static Outer* DereferenceOf(const Inner Outer::*field, const Inner* pointer)
{
if (field != nullptr && pointer != nullptr) {
auto fieldOffset = reinterpret_cast<uintptr_t>(&(static_cast<Outer*>(0)->*field));
auto outPointer = reinterpret_cast<Outer*>(reinterpret_cast<uintptr_t>(pointer) - fieldOffset);
return outPointer;
}
return nullptr;
}
};
class CloseHelp {
public:
template<typename T>
static void DeletePointer(const T* value, bool isArray)
{
if (value == nullptr) {
return;
}
if (isArray) {
delete[] value;
} else {
delete value;
}
}
};
template<typename T>
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_
+191
View File
@@ -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<uint32_t, TimerCallbackInfo*> 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<uv_handle_t*>(&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<napi_value> 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<napi_value> 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<napi_value> 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<std::mutex> 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
+63
View File
@@ -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 <map>
#include <uv.h>
#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<uint32_t, TimerCallbackInfo*> timerTable;
static std::mutex timeLock;
};
} // namespace CompilerRuntime::WorkerModule::Plugin
#endif // JS_WORKER_MODULE_PLUGIN_TIMER_H_
@@ -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
@@ -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 <mutex>
#include <queue>
#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<MessageDataType> queue_;
};
} // namespace OHOS::CCRuntime::Worker
#endif // JSAPI_WORKER_MESSAGE_QUEUE_H_
} // namespace CompilerRuntime::WorkerModule
#endif // JS_WORKER_MODULE_WORKER_MESSAGE_QUEUE_H_
@@ -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<void*>(0),
.reserved = { 0 },
@@ -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
} // namespace CompilerRuntime::WorkerModule
+5 -5
View File
@@ -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 <uv.h>
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_
+160 -182
View File
@@ -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<Worker*> 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<NativeEngine*>(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<uv_async_cb>(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<std::recursive_mutex> 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<std::recursive_mutex> 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<WorkerListener*>::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<std::recursive_mutex> 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<napi_value> scope(argv, true);
Helper::ObjectScope<napi_value> 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<napi_value> scope(argv, true);
Helper::ObjectScope<napi_value> scope(argv, true);
Worker* worker = nullptr;
napi_get_cb_info(env, cbinfo, &argc, argv, nullptr, reinterpret_cast<void**>(&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<napi_value> scope(args, true);
Helper::ObjectScope<napi_value> 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<napi_value> scope(args, true);
Helper::ObjectScope<napi_value> 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<WorkerListener*>::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<napi_value> scope(args, true);
Helper::ObjectScope<napi_value> 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<napi_value> scope(args, true);
Helper::ObjectScope<napi_value> 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<void**>(&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<WorkerListener*>& 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<NativeEngine*>(env);
NativeEngine* engine = reinterpret_cast<NativeEngine*>(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<NativeEngine*>(workerEnv_);
workerEngine->CloseAsyncWork();
CloseHelp::DeletePointer(reinterpret_cast<NativeEngine*>(workerEnv_), false);
Helper::CloseHelp::DeletePointer(reinterpret_cast<NativeEngine*>(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<void**>(&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<napi_value> scope(args, true);
Helper::ObjectScope<napi_value> scope(args, true);
Worker* worker = nullptr;
napi_get_cb_info(env, cbinfo, &argc, args, nullptr, reinterpret_cast<void**>(&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<napi_value> scope(args, true);
Helper::ObjectScope<napi_value> scope(args, true);
Worker* worker = nullptr;
napi_get_cb_info(env, cbinfo, &argc, args, nullptr, reinterpret_cast<void**>(&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<napi_value> scope(args, true);
Helper::ObjectScope<napi_value> scope(args, true);
Worker* worker = nullptr;
napi_get_cb_info(env, cbinfo, &argc, args, nullptr, reinterpret_cast<void**>(&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<WorkerListener*>& 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<WorkerListener*>::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<WorkerListener*>::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
+21 -33
View File
@@ -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 <list>
#include <map>
#include <mutex>
#include <uv.h>
#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<NativeEngine*>(workerEnv_)->GetUVLoop();
return Helper::NapiHelper::GetLibUV(workerEnv_);
}
return nullptr;
}
@@ -375,9 +364,8 @@ public:
void Loop()
{
if (workerEnv_ != nullptr) {
reinterpret_cast<NativeEngine*>(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_
@@ -13,18 +13,16 @@
* limitations under the License.
*/
#include "worker_runner.h"
#include "base/compileruntime/js_worker_module/worker/worker_runner.h"
#include <list>
#include <mutex>
#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
@@ -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 <functional>
#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<void(void*)>;
@@ -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_