mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-03-12 17:05:38 +00:00
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.
This commit is contained in:
parent
07829b90d7
commit
16cfd4764d
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user