diff --git a/BUILD.gn b/BUILD.gn index 065945c80fdfe637f2762633effe1334299db376..97453d088fbb1ea56b19247a7ea362ce9e75dbdd 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -121,6 +121,7 @@ if (defined(ohos_lite)) { ] } } else { + import("//build/config/components/init/param/param_fixer.gni") import("//build/ohos.gni") import("//third_party/libuv/libuv.gni") @@ -302,6 +303,7 @@ if (defined(ohos_lite)) { external_deps += [ "hilog:libhilog", "hitrace:hitrace_meter", + "init:libbegetutil", ] } @@ -338,14 +340,36 @@ if (defined(ohos_lite)) { part_name = "libuv" } + ohos_prebuilt_para("libuv.para") { + source = "libuv.para" + part_name = "libuv" + subsystem_name = "thirdparty" + module_install_dir = "etc/param" + } + + ohos_prebuilt_para("libuv.para.dac") { + source = "libuv.para.dac" + part_name = "libuv" + subsystem_name = "thirdparty" + module_install_dir = "etc/param" + } + ohos_static_library("uv_static") { - deps = [ ":libuv_source" ] + deps = [ + ":libuv.para", + ":libuv.para.dac", + ":libuv_source", + ] public_configs = [ ":libuv_config" ] subsystem_name = "thirdparty" part_name = "libuv" } ohos_shared_library("uv") { - deps = [ ":libuv_source" ] + deps = [ + ":libuv.para", + ":libuv.para.dac", + ":libuv_source", + ] public_configs = [ ":libuv_config" ] subsystem_name = "thirdparty" innerapi_tags = [ "platformsdk" ] diff --git a/bundle.json b/bundle.json index ff7e6701f7897f4ef1c3a6132477ea15dab7926e..0c437879985eb9c61e69d16b76a4d51d308294c3 100644 --- a/bundle.json +++ b/bundle.json @@ -26,7 +26,8 @@ "ffrt", "hilog", "hitrace", - "faultloggerd" + "faultloggerd", + "init" ], "third_party": [] }, diff --git a/libuv.para b/libuv.para new file mode 100644 index 0000000000000000000000000000000000000000..c3077f45a72e832877c6cf90d39f6990953871a0 --- /dev/null +++ b/libuv.para @@ -0,0 +1,14 @@ +# Copyright (c) 2025 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. + +persist.libuv.properties=0 \ No newline at end of file diff --git a/libuv.para.dac b/libuv.para.dac new file mode 100644 index 0000000000000000000000000000000000000000..9722121796b6b298cf9ce4729f49f55e6926b3a4 --- /dev/null +++ b/libuv.para.dac @@ -0,0 +1,14 @@ +# Copyright (c) 2025 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. + + persist.libuv.properties=root:root:0775 \ No newline at end of file diff --git a/src/timer.c b/src/timer.c index 35548b421ca56f39ece914b2aafc17e540b47746..6bae90794b1255f07cce954ecaa4c7f8e955ef39 100644 --- a/src/timer.c +++ b/src/timer.c @@ -59,6 +59,9 @@ static int timer_less_than(const struct heap_node* ha, int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + uv__multi_thread_check_unify(loop, __func__); +#endif uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER); handle->timer_cb = NULL; handle->timeout = 0; @@ -72,6 +75,9 @@ int uv_timer_start(uv_timer_t* handle, uint64_t timeout, uint64_t repeat) { uint64_t clamped_timeout; +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + uv__multi_thread_check_unify(handle->loop, __func__); +#endif if (uv__is_closing(handle) || cb == NULL) return UV_EINVAL; @@ -107,6 +113,9 @@ int uv_timer_start(uv_timer_t* handle, int uv_timer_stop(uv_timer_t* handle) { +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + uv__multi_thread_check_unify(handle->loop, __func__); +#endif if (!uv__is_active(handle)) return 0; diff --git a/src/unix/async.c b/src/unix/async.c index 65a029ca8832bb5ad636c121f28607a8df56f394..1bb30e4de7040fcc263b2804add8f757a5c75727 100644 --- a/src/unix/async.c +++ b/src/unix/async.c @@ -51,6 +51,9 @@ static int uv__async_start(uv_loop_t* loop); int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { int err; +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + uv__multi_thread_check_unify(loop, __func__); +#endif err = uv__async_start(loop); if (err) return err; diff --git a/src/unix/core.c b/src/unix/core.c index ba7c8cef32d667947ad6dface7a70faf147ea355..771dc181710289d3b71e061388a4abeda7b1c8ab 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -147,7 +147,9 @@ uint64_t uv_hrtime(void) { void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { assert(!uv__is_closing(handle)); - +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + uv__multi_thread_check_unify(handle->loop, __func__); +#endif handle->flags |= UV_HANDLE_CLOSING; handle->close_cb = close_cb; @@ -428,6 +430,9 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) { int timeout; int r; int can_sleep; +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + uv__set_thread_id(loop); +#endif if (!is_uv_loop_good_magic(loop)) { return 0; diff --git a/src/unix/loop.c b/src/unix/loop.c index 9832cd107b9fb6ac1fbf42a9abaf6bea04144731..2a304081e7a78092f688f00cb6f947ebfe05920a 100644 --- a/src/unix/loop.c +++ b/src/unix/loop.c @@ -67,6 +67,9 @@ int uv_loop_init(uv_loop_t* loop) { uv__queue_init(&loop->handle_queue); loop->active_handles = 0; +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + uv__init_thread_id(loop); +#endif loop->active_reqs.count = 0; loop->nfds = 0; loop->watchers = NULL; diff --git a/src/uv-common.c b/src/uv-common.c index 13419f494630c3a337f4b8a72a99a50eefd1954d..bece9f9817875a0e12006e69aaa772272364ad5a 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -38,6 +38,16 @@ # include /* AF_UNIX, sockaddr_un */ #endif +#if defined(USE_OHOS_DFX) && defined(__aarch64__) +#include "paramater.h" +#include +#include +static unsigned int g_multi_thread_check = 0; +#endif + +#ifdef USE_FFRT +#include "ffrt_inner.h" +#endif typedef struct { uv_malloc_func local_malloc; @@ -1053,4 +1063,73 @@ uint64_t uv__get_addr_tag(void* addr) { } #endif return tag; -} \ No newline at end of file +} + + +#if defined(USE_OHOS_DFX) && defined(__aarch64__) +static uv_once_t thread_check_guard = UV_ONCE_INIT; +void init_param_once() { + unsigned int param_value = GetIntParameter("persist.libuv.properties", -1); + if (param_value == 1) { + g_multi_thread_check = 1; + } +} + + +int uv__is_multi_thread_open(void) { + uv_once(&thread_check_guard, init_param_once); + if (g_multi_thread_check == 0) { + return 0; + } +#ifdef USE_FFRT + if (ffrt_get_cur_task() != NULL) { + return 0; + } +#endif + return 1; +} + + +void uv__init_thread_id(uv_loop_t* loop) { + if (uv__is_multi_thread_open()) { + uv__loop_internal_fields_t* lfields_tid = uv__get_internal_fields(loop); + lfields_tid->thread_id = 0; + lfields_tid->thread_id |= MULTI_THREAD_CHECK_LOOP_INIT; + } +} + + +void uv__set_thread_id(uv_loop_t* loop) { + if (uv__is_multi_thread_open()) { + uv__loop_internal_fields_t* lfields_tid = uv__get_internal_fields(loop); + lfields_tid->thread_id |= (unsigned int)gettid(); + } +} + + +static unsigned int uv__get_thread_id(const uv_loop_t* loop) { + if (uv__is_multi_thread_open()) { + uv__loop_internal_fields_t* lfields_tid = uv__get_internal_fields(loop); + unsigned int thread_id = lfields_tid->thread_id & ~MULTI_THREAD_CHECK_LOOP_INIT; + return thread_id; + } else { + return 0; + } +} + + +void uv__multi_thread_check_unify(const uv_loop_t* loop, const char* funcName) { + if (!uv__is_multi_thread_open()) { + return; + } + + unsigned int thread_id = uv__get_thread_id(loop); + if (thread_id == 0) { + return; + } + if (thread_id != (unsigned int)gettid()) { + UV_LOGF("multi-thread occurred in function %{public}s!", funcName); + abort(); + } +} +#endif \ No newline at end of file diff --git a/src/uv-common.h b/src/uv-common.h index 7ca246f5762a136852a7f38bba9385491bbea457..4d3be3249b27a8d65231c16c2ef1ebeae39be958 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -41,6 +41,9 @@ # include #endif +#if defined(USE_OHOS_DFX) && defined(__aarch64__) +#define MULTI_THREAD_CHECK_LOOP_INIT 0x80000000 +#endif #if EDOM > 0 # define UV__ERR(x) (-(x)) #else @@ -450,8 +453,17 @@ struct uv__loop_internal_fields_s { #ifdef USE_FFRT struct uv__queue wq_sub[5]; #endif +#if defined(USE_OHOS_DFX) && defined(__aarch64__) + unsigned int thread_id; +#endif }; uint64_t uv__get_addr_tag(void* addr); +#if defined(USE_OHOS_DFX) && defined(__aarch64__) +int uv__is_multi_thread_open(void); +void uv__init_thread_id(uv_loop_t* loop); +void uv__set_thread_id(uv_looop_t* loop); +void uv__multi_thread_check_unify(const uv_loop_t* loop, const char* funcName); +#endif #endif /* UV_COMMON_H_ */