@@ -813,9 +813,59 @@ export default class WASI {
813813 return wasi . ERRNO_BADF ;
814814 }
815815 } ,
816- // eslint-disable-next-line @typescript-eslint/no-unused-vars
817- poll_oneoff ( in_ , out , nsubscriptions ) {
818- throw "async io not supported" ;
816+ async poll_oneoff (
817+ in_ptr : number ,
818+ out_ptr : number ,
819+ nsubscriptions : number ,
820+ ) : Promise < number > {
821+ if ( nsubscriptions === 0 ) {
822+ return wasi . ERRNO_INVAL ;
823+ }
824+ // TODO: For now, we only support a single subscription just to be enough for wasi-libc's
825+ // clock_nanosleep.
826+ if ( nsubscriptions > 1 ) {
827+ return wasi . ERRNO_NOTSUP ;
828+ }
829+
830+ // Read a subscription from the in buffer
831+ const buffer = new DataView ( self . inst . exports . memory . buffer ) ;
832+ const userdata = buffer . getBigUint64 ( in_ptr , true ) ;
833+ const eventtype = buffer . getUint8 ( in_ptr + 8 ) ;
834+ // TODO: For now, we only support clock subscriptions.
835+ if ( eventtype !== wasi . EVENTTYPE_CLOCK ) {
836+ return wasi . ERRNO_NOTSUP ;
837+ }
838+ const clockid = buffer . getUint32 ( in_ptr + 16 , true ) ;
839+ const timeout = buffer . getBigUint64 ( in_ptr + 24 , true ) ;
840+ const flags = buffer . getUint16 ( in_ptr + 36 , true ) ;
841+
842+ // Select timer
843+ let getNow : ( ( ) => bigint ) | undefined = undefined ;
844+ let error : number = wasi . ERRNO_SUCCESS ;
845+ if ( clockid === wasi . CLOCKID_MONOTONIC ) {
846+ getNow = ( ) => BigInt ( Math . round ( performance . now ( ) * 1_000_000 ) ) ;
847+ } else if ( clockid === wasi . CLOCKID_REALTIME ) {
848+ getNow = ( ) => BigInt ( new Date ( ) . getTime ( ) ) * 1_000_000n ;
849+ } else {
850+ getNow = ( ) => BigInt ( 0 ) ;
851+ error = wasi . ERRNO_INVAL ;
852+ }
853+
854+ // Perform the wait
855+ const endTime =
856+ ( flags & wasi . SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME ) !== 0
857+ ? timeout
858+ : getNow ( ) + timeout ;
859+ while ( endTime > getNow ( ) ) {
860+ // block until the timeout is reached
861+ }
862+
863+ // Write an event to the out buffer
864+ buffer . setBigUint64 ( out_ptr , userdata , true ) ;
865+ buffer . setUint16 ( out_ptr + 8 , error , true ) ;
866+ buffer . setUint8 ( out_ptr + 10 , wasi . EVENTTYPE_CLOCK ) ;
867+
868+ return wasi . ERRNO_SUCCESS ;
819869 } ,
820870 proc_exit ( exit_code : number ) {
821871 throw new WASIProcExit ( exit_code ) ;
0 commit comments