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

Fix possible dead lock in wasm_cluster_spawn_exec_env (#2882)

Fix a deadlock issue like:

wasm_runtime_spawn_exec_env
wasm_cluster_spawn_exec_env (hold cluster->lock)
wasm_runtime_instantiate_internal
wasm_instantiate
execute_post_instantiate_functions
wasm_exec_env_set_module_inst (grab the lock again)

Refer to #2879.
Wenyong Huang 2 лет назад
Родитель
Сommit
b008ab4fba
1 измененных файлов с 22 добавлено и 16 удалено
  1. 22 16
      core/iwasm/libraries/thread-mgr/thread_manager.c

+ 22 - 16
core/iwasm/libraries/thread-mgr/thread_manager.c

@@ -488,10 +488,25 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
         return NULL;
     }
 
+    if (!(new_module_inst = wasm_runtime_instantiate_internal(
+              module, module_inst, exec_env, stack_size, 0, NULL, 0))) {
+        return NULL;
+    }
+
+    /* Set custom_data to new module instance */
+    wasm_runtime_set_custom_data_internal(
+        new_module_inst, wasm_runtime_get_custom_data(module_inst));
+
+    wasm_native_inherit_contexts(new_module_inst, module_inst);
+
+    if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst))) {
+        goto fail1;
+    }
+
     os_mutex_lock(&cluster->lock);
 
     if (cluster->has_exception || cluster->processing) {
-        goto fail1;
+        goto fail2;
     }
 
 #if WASM_ENABLE_INTERP != 0
@@ -508,21 +523,11 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
     }
 #endif
 
-    if (!(new_module_inst = wasm_runtime_instantiate_internal(
-              module, module_inst, exec_env, stack_size, 0, NULL, 0))) {
-        goto fail1;
-    }
-
-    /* Set custom_data to new module instance */
-    wasm_runtime_set_custom_data_internal(
-        new_module_inst, wasm_runtime_get_custom_data(module_inst));
-
-    wasm_native_inherit_contexts(new_module_inst, module_inst);
-
     new_exec_env = wasm_exec_env_create_internal(new_module_inst,
                                                  exec_env->wasm_stack_size);
-    if (!new_exec_env)
+    if (!new_exec_env) {
         goto fail2;
+    }
 
     if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) {
         LOG_ERROR("thread manager error: "
@@ -539,8 +544,9 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
     /* Inherit suspend_flags of parent thread */
     new_exec_env->suspend_flags.flags = exec_env->suspend_flags.flags;
 
-    if (!wasm_cluster_add_exec_env(cluster, new_exec_env))
+    if (!wasm_cluster_add_exec_env(cluster, new_exec_env)) {
         goto fail4;
+    }
 
     os_mutex_unlock(&cluster->lock);
 
@@ -552,9 +558,9 @@ fail4:
 fail3:
     wasm_exec_env_destroy_internal(new_exec_env);
 fail2:
-    wasm_runtime_deinstantiate_internal(new_module_inst, true);
-fail1:
     os_mutex_unlock(&cluster->lock);
+fail1:
+    wasm_runtime_deinstantiate_internal(new_module_inst, true);
 
     return NULL;
 }