Просмотр исходного кода

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`.
YAMAMOTO Takashi 3 лет назад
Родитель
Сommit
77ff7daaf4

+ 20 - 0
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()
 {

+ 4 - 0
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();
 

+ 7 - 0
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,

+ 5 - 0
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,

+ 18 - 0
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
  *

+ 42 - 4
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 */