From 77ff7daaf4fc9520b7da9b0e11928ef1dda904fe Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 28 Oct 2022 12:03:39 +0900 Subject: [PATCH] Add wasm_runtime_unregister_natives (#1647) Allow to unregister (or unload) the previously registered native libs, so that no need to restart the whole engine by using `wasm_runtime_destroy/wasm_runtime_init`. --- core/iwasm/common/wasm_native.c | 20 +++++++++++ core/iwasm/common/wasm_native.h | 4 +++ core/iwasm/common/wasm_runtime_common.c | 7 ++++ core/iwasm/common/wasm_runtime_common.h | 5 +++ core/iwasm/include/wasm_export.h | 18 ++++++++++ product-mini/platforms/posix/main.c | 46 ++++++++++++++++++++++--- 6 files changed, 96 insertions(+), 4 deletions(-) diff --git a/core/iwasm/common/wasm_native.c b/core/iwasm/common/wasm_native.c index eb19b6196..91b156d37 100644 --- a/core/iwasm/common/wasm_native.c +++ b/core/iwasm/common/wasm_native.c @@ -356,6 +356,26 @@ wasm_native_register_natives_raw(const char *module_name, true); } +bool +wasm_native_unregister_natives(const char *module_name, + NativeSymbol *native_symbols) +{ + NativeSymbolsNode **prevp; + NativeSymbolsNode *node; + + prevp = &g_native_symbols_list; + while ((node = *prevp) != NULL) { + if (node->native_symbols == native_symbols + && !strcmp(node->module_name, module_name)) { + *prevp = node->next; + wasm_runtime_free(node); + return true; + } + prevp = &node->next; + } + return false; +} + bool wasm_native_init() { diff --git a/core/iwasm/common/wasm_native.h b/core/iwasm/common/wasm_native.h index 2777b38b2..4f6645d25 100644 --- a/core/iwasm/common/wasm_native.h +++ b/core/iwasm/common/wasm_native.h @@ -64,6 +64,10 @@ wasm_native_register_natives_raw(const char *module_name, NativeSymbol *native_symbols, uint32 n_native_symbols); +bool +wasm_native_unregister_natives(const char *module_name, + NativeSymbol *native_symbols); + bool wasm_native_init(); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index cd4ecb708..803603649 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2904,6 +2904,13 @@ wasm_runtime_register_natives_raw(const char *module_name, n_native_symbols); } +bool +wasm_runtime_unregister_natives(const char *module_name, + NativeSymbol *native_symbols) +{ + return wasm_native_unregister_natives(module_name, native_symbols); +} + bool wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr, const WASMType *func_type, const char *signature, diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index e05ada14b..418d4352f 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -864,6 +864,11 @@ wasm_runtime_register_natives_raw(const char *module_name, NativeSymbol *native_symbols, uint32 n_native_symbols); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_unregister_natives(const char *module_name, + NativeSymbol *native_symbols); + bool wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, const WASMType *func_type, const char *signature, diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index b08ebd88e..e3968ff15 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -972,6 +972,24 @@ wasm_runtime_register_natives_raw(const char *module_name, NativeSymbol *native_symbols, uint32_t n_native_symbols); + +/** + * Undo wasm_runtime_register_natives or wasm_runtime_register_natives_raw + * + * @param module_name Should be the same as the corresponding + * wasm_runtime_register_natives. + * (Same in term of strcmp.) + * + * @param native_symbols Should be the same as the corresponding + * wasm_runtime_register_natives. + * (Same in term of pointer comparison.) + * + * @return true if success, false otherwise + */ +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_unregister_natives(const char *module_name, + NativeSymbol *native_symbols); + /** * Get attachment of native function from execution environment * diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index 4834fd508..72f1e29bc 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -245,6 +245,46 @@ load_and_register_native_libs(const char **native_lib_list, return native_handle_count; } + +static void +unregister_and_unload_native_libs(uint32 native_lib_count, + void **native_handle_list) +{ + uint32 i, n_native_symbols; + NativeSymbol *native_symbols; + char *module_name; + void *handle; + + for (i = 0; i < native_lib_count; i++) { + handle = native_handle_list[i]; + + /* lookup get_native_lib func */ + get_native_lib_func get_native_lib = dlsym(handle, "get_native_lib"); + if (!get_native_lib) { + LOG_WARNING("warning: failed to lookup `get_native_lib` function " + "from native lib %p", + handle); + continue; + } + + n_native_symbols = get_native_lib(&module_name, &native_symbols); + if (n_native_symbols == 0 || module_name == NULL + || native_symbols == NULL) { + LOG_WARNING("warning: get_native_lib returned different values for " + "native lib %p", + handle); + continue; + } + + /* unregister native symbols */ + if (!wasm_runtime_unregister_natives(module_name, native_symbols)) { + LOG_WARNING("warning: failed to unregister native lib %p", handle); + continue; + } + + dlclose(handle); + } +} #endif /* BH_HAS_DLFCN */ #if WASM_ENABLE_MULTI_MODULE != 0 @@ -328,7 +368,7 @@ main(int argc, char *argv[]) const char *native_lib_list[8] = { NULL }; uint32 native_lib_count = 0; void *native_handle_list[8] = { NULL }; - uint32 native_handle_count = 0, native_handle_idx; + uint32 native_handle_count = 0; #endif #if WASM_ENABLE_DEBUG_INTERP != 0 char *ip_addr = NULL; @@ -632,9 +672,7 @@ fail2: fail1: #if BH_HAS_DLFCN /* unload the native libraries */ - for (native_handle_idx = 0; native_handle_idx < native_handle_count; - native_handle_idx++) - dlclose(native_handle_list[native_handle_idx]); + unregister_and_unload_native_libs(native_handle_count, native_handle_list); #endif /* destroy runtime environment */