1616#include "debug_engine.h"
1717#endif
1818
19- #if WASM_ENABLE_SHARED_MEMORY != 0
20- #include "wasm_shared_memory.h"
21- #endif
22-
2319typedef struct {
2420 bh_list_link l ;
2521 void (* destroy_cb )(WASMCluster * );
@@ -32,6 +28,8 @@ static bh_list cluster_list_head;
3228static bh_list * const cluster_list = & cluster_list_head ;
3329static korp_mutex cluster_list_lock ;
3430
31+ static korp_mutex _exception_lock ;
32+
3533typedef void (* list_visitor )(void * , void * );
3634
3735static uint32 cluster_max_thread_num = CLUSTER_MAX_THREAD_NUM ;
@@ -52,6 +50,10 @@ thread_manager_init()
5250 return false;
5351 if (os_mutex_init (& cluster_list_lock ) != 0 )
5452 return false;
53+ if (os_mutex_init (& _exception_lock ) != 0 ) {
54+ os_mutex_destroy (& cluster_list_lock );
55+ return false;
56+ }
5557 return true;
5658}
5759
@@ -66,6 +68,7 @@ thread_manager_destroy()
6668 cluster = next ;
6769 }
6870 wasm_cluster_cancel_all_callbacks ();
71+ os_mutex_destroy (& _exception_lock );
6972 os_mutex_destroy (& cluster_list_lock );
7073}
7174
@@ -1240,72 +1243,56 @@ wasm_cluster_resume_all(WASMCluster *cluster)
12401243 os_mutex_unlock (& cluster -> lock );
12411244}
12421245
1246+ struct spread_exception_data {
1247+ WASMExecEnv * skip ;
1248+ const char * exception ;
1249+ };
1250+
12431251static void
12441252set_exception_visitor (void * node , void * user_data )
12451253{
1246- WASMExecEnv * curr_exec_env = (WASMExecEnv * )node ;
1247- WASMExecEnv * exec_env = (WASMExecEnv * )user_data ;
1248- WASMModuleInstanceCommon * module_inst = get_module_inst (exec_env );
1249- WASMModuleInstance * wasm_inst = (WASMModuleInstance * )module_inst ;
1250-
1251- if (curr_exec_env != exec_env ) {
1252- WASMModuleInstance * curr_wasm_inst =
1253- (WASMModuleInstance * )get_module_inst (curr_exec_env );
1254-
1255- /* Only spread non "wasi proc exit" exception */
1256- #if WASM_ENABLE_SHARED_MEMORY != 0
1257- if (curr_wasm_inst -> memory_count > 0 )
1258- shared_memory_lock (curr_wasm_inst -> memories [0 ]);
1259- #endif
1260- if (!strstr (wasm_inst -> cur_exception , "wasi proc exit" )) {
1261- bh_memcpy_s (curr_wasm_inst -> cur_exception ,
1262- sizeof (curr_wasm_inst -> cur_exception ),
1263- wasm_inst -> cur_exception ,
1264- sizeof (wasm_inst -> cur_exception ));
1254+ const struct spread_exception_data * data = user_data ;
1255+ WASMExecEnv * exec_env = (WASMExecEnv * )node ;
1256+
1257+ if (exec_env != data -> skip ) {
1258+ WASMModuleInstance * wasm_inst =
1259+ (WASMModuleInstance * )get_module_inst (exec_env );
1260+
1261+ exception_lock (wasm_inst );
1262+ if (data -> exception != NULL ) {
1263+ /* Only spread non "wasi proc exit" exception */
1264+ if (strcmp (data -> exception , "wasi proc exit" )) {
1265+ snprintf (wasm_inst -> cur_exception ,
1266+ sizeof (wasm_inst -> cur_exception ), "Exception: %s" ,
1267+ data -> exception );
1268+ }
12651269 }
1266- #if WASM_ENABLE_SHARED_MEMORY != 0
1267- if ( curr_wasm_inst -> memory_count > 0 )
1268- shared_memory_unlock ( curr_wasm_inst -> memories [ 0 ]);
1269- #endif
1270+ else {
1271+ wasm_inst -> cur_exception [ 0 ] = '\0' ;
1272+ }
1273+ exception_unlock ( wasm_inst );
12701274
12711275 /* Terminate the thread so it can exit from dead loops */
1272- set_thread_cancel_flags (curr_exec_env );
1273- }
1274- }
1275-
1276- static void
1277- clear_exception_visitor (void * node , void * user_data )
1278- {
1279- WASMExecEnv * exec_env = (WASMExecEnv * )user_data ;
1280- WASMExecEnv * curr_exec_env = (WASMExecEnv * )node ;
1281-
1282- if (curr_exec_env != exec_env ) {
1283- WASMModuleInstance * curr_wasm_inst =
1284- (WASMModuleInstance * )get_module_inst (curr_exec_env );
1285-
1286- #if WASM_ENABLE_SHARED_MEMORY != 0
1287- if (curr_wasm_inst -> memory_count > 0 )
1288- shared_memory_lock (curr_wasm_inst -> memories [0 ]);
1289- #endif
1290- curr_wasm_inst -> cur_exception [0 ] = '\0' ;
1291- #if WASM_ENABLE_SHARED_MEMORY != 0
1292- if (curr_wasm_inst -> memory_count > 0 )
1293- shared_memory_unlock (curr_wasm_inst -> memories [0 ]);
1294- #endif
1276+ if (data -> exception != NULL ) {
1277+ set_thread_cancel_flags (exec_env );
1278+ }
12951279 }
12961280}
12971281
12981282void
1299- wasm_cluster_spread_exception (WASMExecEnv * exec_env , bool clear )
1283+ wasm_cluster_spread_exception (WASMExecEnv * exec_env , const char * exception )
13001284{
1285+ const bool has_exception = exception != NULL ;
13011286 WASMCluster * cluster = wasm_exec_env_get_cluster (exec_env );
13021287 bh_assert (cluster );
13031288
1289+ struct spread_exception_data data ;
1290+ data .skip = exec_env ;
1291+ data .exception = exception ;
1292+
13041293 os_mutex_lock (& cluster -> lock );
1305- cluster -> has_exception = !clear ;
1306- traverse_list (& cluster -> exec_env_list ,
1307- clear ? clear_exception_visitor : set_exception_visitor ,
1308- exec_env );
1294+ cluster -> has_exception = has_exception ;
1295+ traverse_list (& cluster -> exec_env_list , set_exception_visitor , & data );
13091296 os_mutex_unlock (& cluster -> lock );
13101297}
13111298
@@ -1353,3 +1340,21 @@ wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env)
13531340
13541341 return is_thread_terminated ;
13551342}
1343+
1344+ void
1345+ exception_lock (WASMModuleInstance * module_inst )
1346+ {
1347+ /*
1348+ * Note: this lock could be per module instance if desirable.
1349+ * We can revisit on AOT version bump.
1350+ * It probably doesn't matter though because the exception handling
1351+ * logic should not be executed too frequently anyway.
1352+ */
1353+ os_mutex_lock (& _exception_lock );
1354+ }
1355+
1356+ void
1357+ exception_unlock (WASMModuleInstance * module_inst )
1358+ {
1359+ os_mutex_unlock (& _exception_lock );
1360+ }
0 commit comments