diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index f404b4a4a..06ea59098 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -358,24 +358,27 @@ wasm_runtime_unchain_shared_heaps(WASMSharedHeap *head, bool entire_chain) return cur; } -/* Destroy and recycle a shared heap(or head of shared heap chain), return next - * node in the shared heap chain */ -static WASMSharedHeap * -wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head) +/* Destroy and recycle a shared heap(or head of shared heap chain), return + * next node in the shared heap chain through new_head */ +static bool +wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head, + WASMSharedHeap **new_head) { - WASMSharedHeap *cur = NULL, *prev = NULL, *new_head = NULL; + WASMSharedHeap *cur = NULL, *prev = NULL, *next_head = NULL; bool head_found = false, is_chain_head = true; if (!head) { LOG_WARNING("Invalid shared heap to destroy."); - return NULL; + return false; } + *new_head = NULL; + os_mutex_lock(&shared_heap_list_lock); if (head->attached_count != 0) { LOG_WARNING("To destroy shared heap, it needs to be detached first."); os_mutex_unlock(&shared_heap_list_lock); - return NULL; + return false; } for (cur = shared_heap_list; cur; cur = cur->next) { @@ -387,16 +390,16 @@ wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head) if (!head_found) { LOG_WARNING("Shared heap %p isn't tracked by runtime.", head); os_mutex_unlock(&shared_heap_list_lock); - return NULL; + return false; } if (!is_chain_head) { LOG_WARNING("Shared heap %p isn't the head of a shared heap chain.", head); os_mutex_unlock(&shared_heap_list_lock); - return NULL; + return false; } - new_head = head->chain_next; + next_head = head->chain_next; if (head == shared_heap_list) { shared_heap_list = head->next; destroy_shared_heap_node(head); @@ -419,18 +422,29 @@ wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head) LOG_VERBOSE("Destroyed shared heap %p", head); - return new_head; + *new_head = next_head; + + return true; } -WASMSharedHeap * -wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain) +bool +wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain, + WASMSharedHeap **new_head) { - WASMSharedHeap *new_head = NULL; - do { - new_head = wasm_runtime_destroy_shared_heap_head(head); - } while (entire_chain && new_head); + WASMSharedHeap *next_head = NULL; - return new_head; + do { + if (!wasm_runtime_destroy_shared_heap_head(head, &next_head)) { + return false; + } + head = next_head; + } while (entire_chain && head); + + if (new_head) { + *new_head = next_head; + } + + return true; } static uint8 * diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h index 7a52b2b03..3f4779e02 100644 --- a/core/iwasm/common/wasm_memory.h +++ b/core/iwasm/common/wasm_memory.h @@ -95,8 +95,9 @@ wasm_runtime_chain_shared_heaps(WASMSharedHeap *head, WASMSharedHeap *body); WASMSharedHeap * wasm_runtime_unchain_shared_heaps(WASMSharedHeap *head, bool entire_chain); -WASMSharedHeap * -wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain); +bool +wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain, + WASMSharedHeap **new_head); bool wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst, diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 09a650ad4..2f371084e 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -2408,17 +2408,19 @@ wasm_runtime_unchain_shared_heaps(wasm_shared_heap_t head, bool entire_chain); /** * Destroy a shared heap or shared heap chain starting from the given head. * If `entire_chain` is true, destroy the whole chain; otherwise, destroy only - * the head and return the new head of the chain. The shared heap chain must be - * detached before destruction, and only the chain head registered with the - * runtime can be destroyed. + * the head and return the new head of the chain through `new_head`. The shared + * heap chain must be detached before destruction, and only the chain head + * registered with the runtime can be destroyed. * * @param head The head of the shared heap chain to be destroyed. * @param entire_chain Whether to destroy the entire chain. - * @return The new head of the shared heap chain when `entire_chain` is false; - * NULL otherwise. + * @param new_head The new head of the shared heap chain when `entire_chain` is + * false; NULL otherwise. + * @return True if destruction succeeds; false otherwise. */ -WASM_RUNTIME_API_EXTERN wasm_shared_heap_t -wasm_runtime_destroy_shared_heap(wasm_shared_heap_t head, bool entire_chain); +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_destroy_shared_heap(wasm_shared_heap_t head, bool entire_chain, + wasm_shared_heap_t *new_head); /** * Attach a shared heap, it can be the head of shared heap chain, in that case, diff --git a/tests/unit/shared-heap/shared_heap_test.cc b/tests/unit/shared-heap/shared_heap_test.cc index 9dfb8498f..5108abf1c 100644 --- a/tests/unit/shared-heap/shared_heap_test.cc +++ b/tests/unit/shared-heap/shared_heap_test.cc @@ -334,8 +334,9 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_head_only) ASSERT_NE(nullptr, second); - WASMSharedHeap *new_head = - wasm_runtime_destroy_shared_heap(shared_heap_chain, false); + WASMSharedHeap *new_head = nullptr; + ASSERT_TRUE( + wasm_runtime_destroy_shared_heap(shared_heap_chain, false, &new_head)); ASSERT_EQ(second, new_head); ASSERT_EQ(nullptr, new_head->chain_next); @@ -355,8 +356,10 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_entire_chain) FAIL() << "Failed to create shared heap"; } - EXPECT_EQ(nullptr, - wasm_runtime_destroy_shared_heap(shared_heap_chain, true)); + WASMSharedHeap *new_head = nullptr; + EXPECT_TRUE( + wasm_runtime_destroy_shared_heap(shared_heap_chain, true, &new_head)); + EXPECT_EQ(nullptr, new_head); } TEST_F(shared_heap_test, test_destroy_shared_heap_not_chain_head) @@ -372,14 +375,16 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_not_chain_head) ASSERT_NE(nullptr, body); - EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(body, true)); + WASMSharedHeap *new_head = nullptr; + EXPECT_FALSE(wasm_runtime_destroy_shared_heap(body, true, &new_head)); EXPECT_EQ(body, shared_heap_chain->chain_next); test_shared_heap(shared_heap_chain, "test.wasm", "test", 0, argv); EXPECT_EQ(10, argv[0]); - EXPECT_EQ(nullptr, - wasm_runtime_destroy_shared_heap(shared_heap_chain, true)); + EXPECT_TRUE( + wasm_runtime_destroy_shared_heap(shared_heap_chain, true, &new_head)); + EXPECT_EQ(nullptr, new_head); } TEST_F(shared_heap_test, test_destroy_shared_heap_when_attached) @@ -395,63 +400,15 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_when_attached) ASSERT_TRUE(wasm_runtime_attach_shared_heap(module_env.wasm_module_inst, shared_heap)); - EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(shared_heap, true)); + WASMSharedHeap *new_head = nullptr; + EXPECT_FALSE( + wasm_runtime_destroy_shared_heap(shared_heap, true, &new_head)); wasm_runtime_detach_shared_heap(module_env.wasm_module_inst); destroy_module_env(module_env); - EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(shared_heap, true)); -} - -TEST_F(shared_heap_test, test_destroy_invalid_shared_heap) -{ - WASMSharedHeap fake_shared_heap = {}; - - EXPECT_EQ(nullptr, - wasm_runtime_destroy_shared_heap(&fake_shared_heap, true)); -} - -TEST_F(shared_heap_test, test_destroy_shared_heap_untracked_next_head_only) -{ - WASMSharedHeap *shared_heap_chain = nullptr; - WASMSharedHeap *body = nullptr; - WASMSharedHeap fake_shared_heap = {}; - uint32 BUF_SIZE = os_getpagesize(); - - create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2, - BUF_SIZE, &shared_heap_chain); - body = shared_heap_chain->chain_next; - - ASSERT_NE(nullptr, body); - - shared_heap_chain->chain_next = &fake_shared_heap; - EXPECT_EQ(NULL, wasm_runtime_destroy_shared_heap(shared_heap_chain, false)); - shared_heap_chain->chain_next = body; - - EXPECT_EQ(body, wasm_runtime_destroy_shared_heap(shared_heap_chain, false)); - EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(body, true)); -} - -TEST_F(shared_heap_test, test_destroy_shared_heap_untracked_next_entire_chain) -{ - WASMSharedHeap *shared_heap_chain = nullptr; - WASMSharedHeap *body = nullptr; - WASMSharedHeap fake_shared_heap = {}; - uint32 BUF_SIZE = os_getpagesize(); - - create_test_shared_heap_chain(NULL, BUF_SIZE, NULL, BUF_SIZE, - &shared_heap_chain); - body = shared_heap_chain->chain_next; - - ASSERT_NE(nullptr, body); - - shared_heap_chain->chain_next = &fake_shared_heap; - EXPECT_EQ(nullptr, - wasm_runtime_destroy_shared_heap(shared_heap_chain, true)); - - shared_heap_chain->chain_next = body; - EXPECT_EQ(nullptr, - wasm_runtime_destroy_shared_heap(shared_heap_chain, true)); + EXPECT_TRUE(wasm_runtime_destroy_shared_heap(shared_heap, true, &new_head)); + EXPECT_EQ(nullptr, new_head); } TEST_F(shared_heap_test, test_shared_heap_rmw)