diff --git a/include/uv/unix.h b/include/uv/unix.h index 88b1817eae704bd13aa3cf049c5eb1aab56f1e07..09f88a5674280d762c094d956e5dec6971c6a33e 100644 --- a/include/uv/unix.h +++ b/include/uv/unix.h @@ -218,7 +218,6 @@ typedef struct { } uv_lib_t; #define UV_LOOP_PRIVATE_FIELDS \ - unsigned int magic; \ unsigned long flags; \ int backend_fd; \ struct uv__queue pending_queue; \ diff --git a/include/uv/win.h b/include/uv/win.h index 29df8db0572d68b2748cba573dc7653c5a4aa01b..ea50e934b5891ff53665587d62f95e2ee0ac3a4f 100644 --- a/include/uv/win.h +++ b/include/uv/win.h @@ -325,7 +325,6 @@ typedef struct { } uv_lib_t; #define UV_LOOP_PRIVATE_FIELDS \ - unsigned int magic; \ /* The loop's I/O completion port */ \ HANDLE iocp; \ /* The current time according to the event loop. in msecs. */ \ diff --git a/src/threadpool.c b/src/threadpool.c index 4a6d783651fe52ee568728c2abb18f2c2652e0af..fd4f2227779905ed9d3a3488b92e8872f5fbd906 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -92,10 +92,11 @@ void rdunlock_closed_uv_loop_rwlock(void) { int is_uv_loop_good_magic(const uv_loop_t* loop) { - if (loop->magic == UV_LOOP_MAGIC) { + unsigned int magic = uv__get_internal_fields(loop)->magic; + if (magic == UV_LOOP_MAGIC) { return 1; } - UV_LOGE("loop:(%{public}zu:%{public}#x) invalid", (size_t)loop % UV_ADDR_MOD, loop->magic); + UV_LOGE("loop:(%{public}zu:%{public}#x) invalid", (size_t)loop % UV_ADDR_MOD, magic); return 0; } #endif @@ -106,7 +107,7 @@ void on_uv_loop_close(uv_loop_t* loop) { time(&t1); #ifdef USE_FFRT uv_rwlock_wrlock(&g_closed_uv_loop_rwlock); - loop->magic = ~UV_LOOP_MAGIC; + uv__get_internal_fields(loop)->magic = ~UV_LOOP_MAGIC; uv_rwlock_wrunlock(&g_closed_uv_loop_rwlock); #endif time(&t2); @@ -393,8 +394,8 @@ void uv__work_submit_to_eventloop(uv_req_t* req, struct uv__work* w, int qos) { rdlock_closed_uv_loop_rwlock(); if (!is_uv_loop_good_magic(loop)) { rdunlock_closed_uv_loop_rwlock(); - UV_LOGE("uv_loop(%{public}zu:%{public}#x), task is invalid", - (size_t)loop % UV_ADDR_MOD, loop->magic); + UV_LOGE("uv_loop(%{public}zu), task is invalid", + (size_t)loop % UV_ADDR_MOD); return; } diff --git a/src/timer.c b/src/timer.c index 6bb1a45b36b30e6df893a0bfaf7c48afd4049403..6faa905d3e7be389c768f86d8594d2148d5835fb 100644 --- a/src/timer.c +++ b/src/timer.c @@ -59,7 +59,7 @@ 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__) +#if defined(USE_OHOS_DFX) uv__multi_thread_check_unify(loop, __func__); #endif uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER); @@ -75,7 +75,7 @@ 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__) +#if defined(USE_OHOS_DFX) uv__multi_thread_check_unify(handle->loop, __func__); #endif @@ -113,7 +113,7 @@ int uv_timer_start(uv_timer_t* handle, int uv_timer_stop(uv_timer_t* handle) { -#if defined(USE_OHOS_DFX) && defined(__aarch64__) +#if defined(USE_OHOS_DFX) uv__multi_thread_check_unify(handle->loop, __func__); #endif if (!uv__is_active(handle)) diff --git a/src/unix/async.c b/src/unix/async.c index eef434ffad56e1c2f5cd0f329c2c833a3eb1a7df..3c25f26d03a972a82118a5d9dcd4ae246635ecca 100644 --- a/src/unix/async.c +++ b/src/unix/async.c @@ -44,6 +44,10 @@ #include "c/executor_task.h" #endif +#if defined(USE_OHOS_DFX) +#define TRAVERSE_RANGE 10 +#endif + static void uv__async_send(uv_async_t* handle); static int uv__async_start(uv_loop_t* loop); @@ -51,8 +55,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__) +#if defined(USE_OHOS_DFX) uv__multi_thread_check_unify(loop, __func__); + uv__get_internal_fields(loop)->async_handles_cnt++; #endif err = uv__async_start(loop); if (err) @@ -100,6 +105,9 @@ int uv_async_send(uv_async_t* handle) { void uv__async_close(uv_async_t* handle) { atomic_exchange((_Atomic int*) &handle->pending, 0); uv__queue_remove(&handle->queue); +#ifdef USE_OHOS_DFX + uv__get_internal_fields(handle->loop)->async_handles_cnt--; +#endif uv__handle_stop(handle); } @@ -137,8 +145,17 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { #endif } +#ifdef USE_OHOS_DFX + int cnt = uv__get_internal_fields(loop)->async_handles_cnt + TRAVERSE_RANGE; +#endif uv__queue_move(&loop->async_handles, &queue); while (!uv__queue_empty(&queue)) { +#ifdef USE_OHOS_DFX + if (cnt-- < 0) { + UV_LOGE("eventloop maybe stuck in infinite loop:%{public}zu", (size_t)loop % UV_ADDR_MOD); + break; + } +#endif q = uv__queue_head(&queue); h = uv__queue_data(q, uv_async_t, queue); diff --git a/src/unix/core.c b/src/unix/core.c index 1a2eb5a3172089d1f08dd2e03c1fa0cdae9ed11b..64107e17c5c73cf96b091966e343e9de702809a5 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -147,7 +147,7 @@ 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__) +#if defined(USE_OHOS_DFX) uv__multi_thread_check_unify(handle->loop, __func__); #endif handle->flags |= UV_HANDLE_CLOSING; @@ -430,7 +430,7 @@ 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__) +#if defined(USE_OHOS_DFX) uv__set_thread_id(loop); #endif @@ -1939,7 +1939,7 @@ unsigned int uv_available_parallelism(void) { int uv_register_task_to_event(struct uv_loop_s* loop, uv_post_task func, void* handler) { -#if defined(__aarch64__) +#if defined(USE_OHOS_DFX) if (loop == NULL) return -1; @@ -1962,7 +1962,7 @@ int uv_register_task_to_event(struct uv_loop_s* loop, uv_post_task func, void* h int uv_unregister_task_to_event(struct uv_loop_s* loop) { -#if defined(__aarch64__) +#if defined(USE_OHOS_DFX) uv__loop_internal_fields_t* lfields_flag = uv__get_internal_fields(loop); if (loop == NULL || loop->data == NULL || lfields_flag->register_flag == 0) return -1; @@ -1977,7 +1977,7 @@ int uv_unregister_task_to_event(struct uv_loop_s* loop) int uv_check_data_valid(uv_loop_t* loop) { -#if defined(__aarch64__) +#if defined(USE_OHOS_DFX) uv__loop_internal_fields_t* lfields_flag = uv__get_internal_fields(loop); if (loop == NULL || loop->data == NULL || lfields_flag->register_flag == 0) { return -1; diff --git a/src/unix/loop.c b/src/unix/loop.c index e841f88afc96cc4d9fa6d228179baa2fdeff0822..54dd1eee9bb405ffde91deadf06f4147a459635f 100644 --- a/src/unix/loop.c +++ b/src/unix/loop.c @@ -59,6 +59,7 @@ int uv_loop_init(uv_loop_t* loop) { uv__queue_init(&(lfields_qos->wq_sub[uv_qos_user_initiated])); uv__queue_init(&(lfields_qos->wq_sub[uv_qos_reserved])); uv__queue_init(&(lfields_qos->wq_sub[uv_qos_user_interactive])); + lfields_qos->magic = UV_LOOP_MAGIC; #endif uv__queue_init(&loop->idle_handles); @@ -68,12 +69,11 @@ 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__) +#if defined(USE_OHOS_DFX) uv__init_thread_id(loop); -#endif -#ifdef __aarch64__ - uv__loop_internal_fields_t* lfields_flag = uv__get_internal_fields(loop); - lfields_flag->register_flag = 0; + uv__loop_internal_fields_t* lfields_dfx = uv__get_internal_fields(loop); + lfields_dfx->register_flag = 0; + lfields_dfx->async_handles_cnt = 0; #endif loop->active_reqs.count = 0; loop->nfds = 0; @@ -119,9 +119,6 @@ int uv_loop_init(uv_loop_t* loop) { uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV_HANDLE_INTERNAL; -#ifdef USE_FFRT - loop->magic = UV_LOOP_MAGIC; -#endif return 0; fail_async_init: @@ -229,12 +226,12 @@ void uv__loop_close(uv_loop_t* loop) { loop->nwatchers = 0; lfields = uv__get_internal_fields(loop); +#ifdef USE_FFRT + lfields->magic = ~UV_LOOP_MAGIC; +#endif uv_mutex_destroy(&lfields->loop_metrics.lock); uv__free(lfields); loop->internal_fields = NULL; -#ifdef USE_FFRT - loop->magic = ~UV_LOOP_MAGIC; -#endif } diff --git a/src/uv-common.c b/src/uv-common.c index aeeab7d891fecfe3a5edf78138d30a8d6b0025d8..c895ecb7ae326b34ced3f1b15fe7d45b798c808d 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -38,7 +38,7 @@ # include /* AF_UNIX, sockaddr_un */ #endif -#if defined(USE_OHOS_DFX) && defined(__aarch64__) +#if defined(USE_OHOS_DFX) #include "parameter.h" #include #include @@ -1081,7 +1081,7 @@ int uv__copy_taskname(uv_req_t* req, const char* task_name) { #endif -#if defined(USE_OHOS_DFX) && defined(__aarch64__) +#if defined(USE_OHOS_DFX) static uv_once_t thread_check_guard = UV_ONCE_INIT; void init_param_once() { int param_value = GetIntParameter("persist.libuv.properties", -1); diff --git a/src/uv-common.h b/src/uv-common.h index 7319cac6e11285225a42868ec9c274471729faf4..f9bcdd2c0f5ea0327d484c80cb081f2c96959454 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -453,18 +453,18 @@ struct uv__loop_internal_fields_s { #endif /* __linux__ */ #ifdef USE_FFRT struct uv__queue wq_sub[6]; + unsigned int magic; #endif -#if defined(USE_OHOS_DFX) && defined(__aarch64__) +#if defined(USE_OHOS_DFX) unsigned int thread_id; -#endif -#ifdef __aarch64__ unsigned int register_flag; + int async_handles_cnt; #endif }; uint64_t uv__get_addr_tag(void* addr); -#if defined(USE_OHOS_DFX) && defined(__aarch64__) +#if defined(USE_OHOS_DFX) int uv__is_multi_thread_open(void); void uv__init_thread_id(uv_loop_t* loop); void uv__set_thread_id(uv_loop_t* loop);