@@ -63,6 +63,12 @@ typedef struct WASIContext {
6363wasi_ctx_t
6464wasm_runtime_get_wasi_ctx (wasm_module_inst_t module_inst );
6565
66+ static inline size_t
67+ min (size_t a , size_t b )
68+ {
69+ return a > b ? b : a ;
70+ }
71+
6672static inline struct fd_table *
6773wasi_ctx_get_curfds (wasm_module_inst_t module_inst , wasi_ctx_t wasi_ctx )
6874{
@@ -951,14 +957,105 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
951957 return wasmtime_ssp_path_remove_directory (curfds , fd , path , path_len );
952958}
953959
960+ #if WASM_ENABLE_THREAD_MGR != 0
961+ static __wasi_timestamp_t
962+ get_timeout_for_poll_oneoff (const wasi_subscription_t * in ,
963+ uint32 nsubscriptions )
964+ {
965+ __wasi_timestamp_t timeout = (__wasi_timestamp_t )- 1 ;
966+ uint32 i = 0 ;
967+
968+ for (i = 0 ; i < nsubscriptions ; ++ i ) {
969+ const __wasi_subscription_t * s = & in [i ];
970+ if (s -> u .type == __WASI_EVENTTYPE_CLOCK
971+ && (s -> u .u .clock .flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME ) == 0 ) {
972+ timeout = min (timeout , s -> u .u .clock .timeout );
973+ }
974+ }
975+ return timeout ;
976+ }
977+
978+ static void
979+ update_clock_subscription_data (wasi_subscription_t * in , uint32 nsubscriptions ,
980+ const wasi_timestamp_t new_timeout )
981+ {
982+ uint32 i = 0 ;
983+ for (i = 0 ; i < nsubscriptions ; ++ i ) {
984+ __wasi_subscription_t * s = & in [i ];
985+ if (s -> u .type == __WASI_EVENTTYPE_CLOCK ) {
986+ s -> u .u .clock .timeout = new_timeout ;
987+ }
988+ }
989+ }
990+
991+ static wasi_errno_t
992+ execute_interruptible_poll_oneoff (wasm_module_inst_t module_inst ,
993+ #if !defined(WASMTIME_SSP_STATIC_CURFDS )
994+ struct fd_table * curfds ,
995+ #endif
996+ const __wasi_subscription_t * in ,
997+ __wasi_event_t * out , size_t nsubscriptions ,
998+ size_t * nevents )
999+ {
1000+ if (nsubscriptions == 0 ) {
1001+ * nevents = 0 ;
1002+ return __WASI_ESUCCESS ;
1003+ }
1004+
1005+ wasi_errno_t err ;
1006+ __wasi_timestamp_t elapsed = 0 ;
1007+
1008+ const __wasi_timestamp_t timeout = get_timeout_for_poll_oneoff (
1009+ in , nsubscriptions ),
1010+ time_quant = 1e9 ;
1011+ const uint64 size_to_copy =
1012+ nsubscriptions * (uint64 )sizeof (wasi_subscription_t );
1013+ __wasi_subscription_t * in_copy = NULL ;
1014+
1015+ if (size_to_copy >= UINT32_MAX
1016+ || !(in_copy = (__wasi_subscription_t * )wasm_runtime_malloc (
1017+ (uint32 )size_to_copy ))) {
1018+ return __WASI_ENOMEM ;
1019+ }
1020+
1021+ bh_memcpy_s (in_copy , size_to_copy , in , size_to_copy );
1022+
1023+ while (timeout == (__wasi_timestamp_t )- 1 || elapsed <= timeout ) {
1024+ elapsed += time_quant ;
1025+
1026+ /* update timeout for clock subscription events */
1027+ update_clock_subscription_data (in_copy , nsubscriptions ,
1028+ min (time_quant , timeout - elapsed ));
1029+ err = wasmtime_ssp_poll_oneoff (curfds , in_copy , out , nsubscriptions ,
1030+ nevents );
1031+ if (err ) {
1032+ wasm_runtime_free (in_copy );
1033+ return err ;
1034+ }
1035+
1036+ if (wasm_runtime_get_exception (module_inst ) || * nevents > 0 ) {
1037+ wasm_runtime_free (in_copy );
1038+
1039+ if (* nevents ) {
1040+ return __WASI_ESUCCESS ;
1041+ }
1042+ return EINTR ;
1043+ }
1044+ }
1045+
1046+ wasm_runtime_free (in_copy );
1047+ return __WASI_ESUCCESS ;
1048+ }
1049+ #endif
1050+
9541051static wasi_errno_t
9551052wasi_poll_oneoff (wasm_exec_env_t exec_env , const wasi_subscription_t * in ,
9561053 wasi_event_t * out , uint32 nsubscriptions , uint32 * nevents_app )
9571054{
9581055 wasm_module_inst_t module_inst = get_module_inst (exec_env );
9591056 wasi_ctx_t wasi_ctx = get_wasi_ctx (module_inst );
9601057 struct fd_table * curfds = wasi_ctx_get_curfds (module_inst , wasi_ctx );
961- size_t nevents ;
1058+ size_t nevents = 0 ;
9621059 wasi_errno_t err ;
9631060
9641061 if (!wasi_ctx )
@@ -969,7 +1066,12 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
9691066 || !validate_native_addr (nevents_app , sizeof (uint32 )))
9701067 return (wasi_errno_t )- 1 ;
9711068
1069+ #if WASM_ENABLE_THREAD_MGR == 0
9721070 err = wasmtime_ssp_poll_oneoff (curfds , in , out , nsubscriptions , & nevents );
1071+ #else
1072+ err = execute_interruptible_poll_oneoff (module_inst , curfds , in , out ,
1073+ nsubscriptions , & nevents );
1074+ #endif
9731075 if (err )
9741076 return err ;
9751077
@@ -1861,12 +1963,6 @@ allocate_iovec_app_buffer(wasm_module_inst_t module_inst,
18611963 return __WASI_ESUCCESS ;
18621964}
18631965
1864- static inline size_t
1865- min (size_t a , size_t b )
1866- {
1867- return a > b ? b : a ;
1868- }
1869-
18701966static wasi_errno_t
18711967copy_buffer_to_iovec_app (wasm_module_inst_t module_inst , uint8 * buf_begin ,
18721968 uint32 buf_size , iovec_app_t * data , uint32 data_len ,
0 commit comments