Add an API to terminate instance (#2538)
Add API wasm_runtime_terminate to terminate a module instance by setting "terminated by user" exception to the module instance. And update the product-mini of posix platforms. Note: this doesn't work for some situations like blocking system calls.
This commit is contained in:
@ -2342,8 +2342,8 @@ wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm)
|
||||
return module_inst->exec_env_singleton;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
static void
|
||||
wasm_set_exception_local(WASMModuleInstance *module_inst, const char *exception)
|
||||
{
|
||||
exception_lock(module_inst);
|
||||
if (exception) {
|
||||
@ -2354,13 +2354,22 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
module_inst->cur_exception[0] = '\0';
|
||||
}
|
||||
exception_unlock(module_inst);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
{
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
WASMExecEnv *exec_env =
|
||||
wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
|
||||
if (exec_env) {
|
||||
wasm_cluster_spread_exception(exec_env, exception);
|
||||
wasm_cluster_set_exception(exec_env, exception);
|
||||
}
|
||||
else {
|
||||
wasm_set_exception_local(module_inst, exception);
|
||||
}
|
||||
#else
|
||||
wasm_set_exception_local(module_inst, exception);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2468,6 +2477,18 @@ wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||
wasm_runtime_set_exception(module_inst_comm, NULL);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
void
|
||||
wasm_runtime_terminate(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
wasm_set_exception(module_inst, "terminated by user");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
WASMModuleInstanceCommon *module_inst_comm, void *custom_data)
|
||||
|
||||
@ -675,6 +675,10 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module);
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_terminate(WASMModuleInstanceCommon *module);
|
||||
|
||||
/* Internal API */
|
||||
void
|
||||
wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst,
|
||||
|
||||
@ -894,6 +894,27 @@ wasm_runtime_set_exception(wasm_module_inst_t module_inst,
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_clear_exception(wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* Terminate the WASM module instance.
|
||||
*
|
||||
* This function causes the module instance fail as if it raised a trap.
|
||||
*
|
||||
* This is intended to be used in situations like:
|
||||
*
|
||||
* - A thread is executing the WASM module instance
|
||||
* (eg. it's in the middle of `wasm_application_execute_main`)
|
||||
*
|
||||
* - Another thread has a copy of `wasm_module_inst_t` of
|
||||
* the module instance and wants to terminate it asynchronously.
|
||||
*
|
||||
* This function is provided only when WAMR is built with threading enabled.
|
||||
* (`WASM_ENABLE_THREAD_MGR=1`)
|
||||
*
|
||||
* @param module_inst the WASM module instance
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_terminate(wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* Set custom data to WASM module instance.
|
||||
* Note:
|
||||
|
||||
@ -1061,6 +1061,15 @@ set_thread_cancel_flags(WASMExecEnv *exec_env)
|
||||
os_mutex_unlock(&exec_env->wait_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_thread_cancel_flags(WASMExecEnv *exec_env)
|
||||
{
|
||||
os_mutex_lock(&exec_env->wait_lock);
|
||||
WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags,
|
||||
~WASM_SUSPEND_FLAG_TERMINATE);
|
||||
os_mutex_unlock(&exec_env->wait_lock);
|
||||
}
|
||||
|
||||
int32
|
||||
wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
|
||||
{
|
||||
@ -1266,18 +1275,21 @@ set_exception_visitor(void *node, void *user_data)
|
||||
if (data->exception != NULL) {
|
||||
set_thread_cancel_flags(exec_env);
|
||||
}
|
||||
else {
|
||||
clear_thread_cancel_flags(exec_env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception)
|
||||
wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception)
|
||||
{
|
||||
const bool has_exception = exception != NULL;
|
||||
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||
bh_assert(cluster);
|
||||
|
||||
struct spread_exception_data data;
|
||||
data.skip = exec_env;
|
||||
data.skip = NULL;
|
||||
data.exception = exception;
|
||||
|
||||
os_mutex_lock(&cluster->lock);
|
||||
|
||||
@ -139,7 +139,7 @@ WASMExecEnv *
|
||||
wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst);
|
||||
|
||||
void
|
||||
wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception);
|
||||
wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception);
|
||||
|
||||
WASMExecEnv *
|
||||
wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env);
|
||||
|
||||
Reference in New Issue
Block a user