From 16cfd4764dfdcde85ee7c2f6f598108da528f7bd Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Fri, 6 May 2022 12:52:17 +0800 Subject: [PATCH] Fix atomic wait not thread safe issue (#1146) Add lock for acquire_wait_info and release_wait_info, and remove release_wait_info in wasm_runtime_atomic_notify. --- core/iwasm/common/wasm_shared_memory.c | 40 +++++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index 985861972..a0b4001e4 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -224,17 +224,22 @@ acquire_wait_info(void *address, bool create) AtomicWaitInfo *wait_info = NULL; bh_list_status ret; + os_mutex_lock(&shared_memory_list_lock); + if (address) wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address); - if (!create) + if (!create) { + os_mutex_unlock(&shared_memory_list_lock); return wait_info; + } /* No wait info on this address, create new info */ if (!wait_info) { if (!(wait_info = (AtomicWaitInfo *)wasm_runtime_malloc( - sizeof(AtomicWaitInfo)))) - return NULL; + sizeof(AtomicWaitInfo)))) { + goto fail1; + } memset(wait_info, 0, sizeof(AtomicWaitInfo)); /* init wait list */ @@ -244,20 +249,30 @@ acquire_wait_info(void *address, bool create) /* init wait list lock */ if (0 != os_mutex_init(&wait_info->wait_list_lock)) { - wasm_runtime_free(wait_info); - return NULL; + goto fail2; } if (!bh_hash_map_insert(wait_map, address, (void *)wait_info)) { - os_mutex_destroy(&wait_info->wait_list_lock); - wasm_runtime_free(wait_info); - return NULL; + goto fail3; } } + os_mutex_unlock(&shared_memory_list_lock); + bh_assert(wait_info); (void)ret; return wait_info; + +fail3: + os_mutex_destroy(&wait_info->wait_list_lock); + +fail2: + wasm_runtime_free(wait_info); + +fail1: + os_mutex_unlock(&shared_memory_list_lock); + + return NULL; } static void @@ -285,10 +300,14 @@ destroy_wait_info(void *wait_info) static void release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, void *address) { + os_mutex_lock(&shared_memory_list_lock); + if (wait_info->wait_list->len == 0) { bh_hash_map_remove(wait_map_, address, NULL, NULL); destroy_wait_info(wait_info); } + + os_mutex_unlock(&shared_memory_list_lock); } uint32 @@ -405,8 +424,9 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, uint32 notify_result; AtomicWaitInfo *wait_info; - /* Nobody wait on this address */ wait_info = acquire_wait_info(address, false); + + /* Nobody wait on this address */ if (!wait_info) return 0; @@ -414,7 +434,5 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, notify_result = notify_wait_list(wait_info->wait_list, count); os_mutex_unlock(&wait_info->wait_list_lock); - release_wait_info(wait_map, wait_info, address); - return notify_result; }