From 7e9fdf58bd1e0fa1938ece5b7bc279b0b5d79638 Mon Sep 17 00:00:00 2001 From: liaoxingxing Date: Sun, 11 Aug 2024 15:15:59 +0800 Subject: [PATCH] data race bug fix Signed-off-by: liaoxingxing --- src/threadpool.c | 5 +++-- src/unix/internal.h | 33 +++++++++++++++++++++++++++++++++ src/uv-common.h | 17 +++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/threadpool.c b/src/threadpool.c index 3aefe7c..14d9937 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -771,20 +771,21 @@ void uv__ffrt_work(ffrt_executor_task_t* data, ffrt_qos_t qos) #ifdef UV_STATISTIC uv__post_statistic_work(w, WORK_END); #endif - uv__loop_internal_fields_t* lfields = uv__get_internal_fields(loop); rdlock_closed_uv_loop_rwlock(); + uv__loop_internal_fields_t* lfields = uv__get_internal_fields(loop); + uv_mutex_lock(&loop->wq_mutex); if (loop->magic != UV_LOOP_MAGIC || !lfields || qos >= ARRAY_SIZE(lfields->wq_sub) || !lfields->wq_sub[qos].next || !lfields->wq_sub[qos].prev) { + uv_mutex_unlock(&loop->wq_mutex); rdunlock_closed_uv_loop_rwlock(); UV_LOGE("uv_loop(%{public}zu:%{public}#x) in task(%p:%p) is invalid", (size_t)loop, loop->magic, req->work_cb, req->after_work_cb); return; } - uv_mutex_lock(&loop->wq_mutex); w->work = NULL; /* Signal uv_cancel() that the work req is done executing. */ if (uv_check_data_valid((struct uv_loop_data*)(loop->data)) == 0) { diff --git a/src/unix/internal.h b/src/unix/internal.h index 80e596a..d4b3273 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -472,4 +472,37 @@ uv__fs_copy_file_range(int fd_in, #define UV__CPU_AFFINITY_SUPPORTED 0 #endif +UV_UNUSED(static int uv__atomic_self_increase(int* ptr)) { +#if defined(__i386__) || defined(__x86_64__) + __asm__ __volatile__("lock; addl $1, %0" + : "=m" (*ptr) + : "m" (*ptr) + : "memory"); + return *ptr; +#elif defined(__MVS__) + __asm("add $1, %0" : "+r"(*ptr)); + return *ptr; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + return atomic_add_32((volatile uint32_t *)ptr, 1); +#else + return __sync_fetch_and_add(ptr, 1); +#endif +} + +UV_UNUSED(static int uv__atomic_self_decrease(int* ptr)) { +#if defined(__i386__) || defined(__x86_64__) + __asm__ __volatile__("lock; subl $1, %0" + : "=m" (*ptr) + : "m" (*ptr) + : "memory"); + return *ptr; +#elif defined(__MVS__) + __asm("sub $1, %0" : "+r"(*ptr)); + return *ptr; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + return atomic_sub_32((volatile uint32_t *)ptr, 1); +#else + return __sync_fetch_and_sub(ptr, 1); +#endif +} #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/src/uv-common.h b/src/uv-common.h index bcff87a..24c6d3e 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -236,18 +236,35 @@ void uv__threadpool_cleanup(void); #define uv__has_active_reqs(loop) \ ((loop)->active_reqs.count > 0) +#ifndef _WIN32 +#define uv__req_register(loop, req) \ + do { \ + uv__atomic_self_increase((int*)(&((loop)->active_reqs.count))); \ + } \ + while (0) +#else #define uv__req_register(loop, req) \ do { \ (loop)->active_reqs.count++; \ } \ while (0) +#endif +#ifndef _WIN32 +#define uv__req_unregister(loop, req) \ + do { \ + assert(uv__has_active_reqs(loop)); \ + uv__atomic_self_decrease((int*)(&((loop)->active_reqs.count))); \ + } \ + while (0) +#else #define uv__req_unregister(loop, req) \ do { \ assert(uv__has_active_reqs(loop)); \ (loop)->active_reqs.count--; \ } \ while (0) +#endif #define uv__has_active_handles(loop) \ ((loop)->active_handles > 0) -- Gitee