@@ -600,15 +600,49 @@ var SyscallsLibrary = {
600600 return 0 ;
601601 } ,
602602 __syscall__newselect__i53abi : true ,
603- __syscall__newselect__deps : [ '$parseSelectFDSet' ] ,
603+ __syscall__newselect__proxy : 'none ',
604+ __syscall__newselect__deps : [ '_newselect_js' ,
605+ #if PTHREADS
606+ '_emscripten_proxy_newselect' ,
607+ #endif
608+ ] ,
604609 __syscall__newselect : ( nfds , readfds , writefds , exceptfds , timeoutInMillis ) = > {
610+ #if PTHREADS
611+ if ( ENVIRONMENT_IS_PTHREAD ) {
612+ return __emscripten_proxy_newselect ( nfds ,
613+ { { { to64 ( 'readfds' ) } } } ,
614+ { { { to64 ( 'writefds' ) } } } ,
615+ { { { to64 ( 'exceptfds' ) } } } ,
616+ { { { splitI64 ( 'timeoutInMillis' ) } } } ) ;
617+ }
618+ #endif
619+ return __newselect_js ( { { { to64 ( '0 ') } } } ,
620+ { { { to64 ( '0' ) } } } ,
621+ nfds ,
622+ { { { to64 ( 'readfds' ) } } } ,
623+ { { { to64 ( 'writefds' ) } } } ,
624+ { { { to64 ( 'exceptfds' ) } } } ,
625+ { { { splitI64 ( 'timeoutInMillis' ) } } } ) ;
626+ } ,
627+ _newselect_js__i53abi : true ,
628+ _newselect_js__proxy : 'none' ,
629+ _newselect_js__deps : [ '$parseSelectFDSet' ,
630+ #if PTHREADS
631+ '_emscripten_proxy_newselect_finish' ,
632+ #endif
633+ ] ,
634+ _newselect_js : ( ctx , arg , nfds , readfds , writefds , exceptfds , timeoutInMillis ) = > {
605635 // readfds are supported,
606636 // writefds checks socket open status
607637 // exceptfds are supported, although on web, such exceptional conditions never arise in web sockets
608638 // and so the exceptfds list will always return empty.
609- // timeout is supported, although on SOCKFS and PIPEFS these are ignored and always treated as 0 - fully async
639+ // timeout is supported, although on SOCKFS these are ignored and always treated as 0 - fully async
640+ // and PIPEFS supports timeout only when the select is called from a worker.
610641#if ASSERTIONS
611642 assert ( nfds <= 64 , 'nfds must be less than or equal to 64' ) ; // fd sets have 64 bits // TODO: this could be 1024 based on current musl headers
643+ #if PTHREADS
644+ assert ( ! ENVIRONMENT_IS_PTHREAD , '_newselect_js must be called in the main thread' ) ;
645+ #endif
612646#endif
613647
614648 var fdSet = parseSelectFDSet ( readfds , writefds , exceptfds ) ;
@@ -618,6 +652,36 @@ var SyscallsLibrary = {
618652
619653 var check = ( fd , low , high , val ) => fd < 32 ? ( low & val ) : ( high & val ) ;
620654
655+ #if PTHREADS
656+ var makeNotifyCallback = null ;
657+ if ( ctx ) {
658+ // Enable event handlers only when the select call is proxied from a worker.
659+ var cleanupFuncs = [ ] ;
660+ var notifyDone = false ;
661+ makeNotifyCallback = ( fd ) => {
662+ var cb = ( flags ) => {
663+ if ( notifyDone ) {
664+ return ;
665+ }
666+ if ( fd >= 0 ) {
667+ fdSet . setFlags ( fd , flags ) ;
668+ }
669+ notifyDone = true ;
670+ cleanupFuncs . forEach ( cb => cb ( ) ) ;
671+ fdSet . commit ( ) ;
672+ __emscripten_proxy_newselect_finish ( { { { to64 ( 'ctx' ) } } } , { { { to64 ( 'arg' ) } } } , fdSet . getTotal ( ) ) ;
673+ }
674+ cb . registerCleanupFunc = ( f ) => {
675+ if ( f != null ) cleanupFuncs . push ( f ) ;
676+ }
677+ return cb ;
678+ }
679+ if ( timeoutInMillis > 0 ) {
680+ setTimeout ( ( ) => makeNotifyCallback ( - 1 ) ( 0 ) , timeoutInMillis ) ;
681+ }
682+ }
683+ #endif
684+
621685 for ( var fd = 0 ; fd < nfds ; fd ++ ) {
622686 var mask = 1 << ( fd % 32 ) ;
623687 if ( ! ( check ( fd , allLow , allHigh , mask ) ) ) {
@@ -629,7 +693,14 @@ var SyscallsLibrary = {
629693 var flags = SYSCALLS . DEFAULT_POLLMASK ;
630694
631695 if ( stream . stream_ops . poll ) {
632- flags = stream . stream_ops . poll ( stream , timeoutInMillis ) ;
696+ flags = ( ( ) => {
697+ #if PTHREADS
698+ if ( makeNotifyCallback != null ) {
699+ return stream . stream_ops . poll ( stream , timeoutInMillis , timeoutInMillis != 0 ? makeNotifyCallback ( fd ) : null ) ;
700+ }
701+ #endif
702+ return stream . stream_ops . poll ( stream , timeoutInMillis ) ;
703+ } ) ( ) ;
633704 } else {
634705#if ASSERTIONS
635706 if ( timeoutInMillis != 0 ) warnOnce ( 'non-zero select() timeout not supported: ' + timeoutInMillis )
@@ -639,6 +710,14 @@ var SyscallsLibrary = {
639710 fdSet . setFlags ( fd , flags ) ;
640711 }
641712
713+ #if PTHREADS
714+ if ( makeNotifyCallback != null ) {
715+ if ( ( fdSet . getTotal ( ) > 0 ) || ( timeoutInMillis == 0 ) ) {
716+ makeNotifyCallback ( - 1 ) ( 0 ) ;
717+ }
718+ return 0 ;
719+ }
720+ #endif
642721
643722 fdSet . commit ( ) ;
644723
0 commit comments