@@ -1069,6 +1069,83 @@ var LibraryPThread = {
10691069#endif
10701070 } ,
10711071
1072+ #if MAIN_MODULE
1073+ $promiseMap : "new Map ( ) ; ",
1074+ $nextPromiseId : 1 ,
1075+
1076+ // Create a new promise that can be resolved or rejected by passing
1077+ // a unique ID to emscripten_promise_resolve/emscripten_promise_reject
1078+ $newNativePromise__deps : [ '$promiseMap' , '$nextPromiseId' ] ,
1079+ $newNativePromise : function ( func , args ) {
1080+ return new Promise ( ( resolve , reject ) => {
1081+ var promiseId = nextPromiseId ;
1082+ nextPromiseId += 1 ;
1083+ promiseMap . set ( promiseId , { resolve, reject} ) ;
1084+ // Native promise function take promise ID as last argument
1085+ args . push ( promiseId ) ;
1086+ func . apply ( null , args ) ;
1087+ } ) ;
1088+ } ,
1089+
1090+ emscripten_promise_resolve__deps : [ '$promiseMap' ] ,
1091+ emscripten_promise_resolve__sig : 'vip' ,
1092+ emscripten_promise_resolve : function ( id , value ) {
1093+ #if RUNTIME_DEBUG
1094+ err ( 'emscripten_resolve_promise: ' + id ) ;
1095+ #endif
1096+ assert ( promiseMap . has ( id ) ) ;
1097+ promiseMap . get ( id ) . resolve ( value ) ;
1098+ promiseMap . delete ( id ) ;
1099+ } ,
1100+
1101+ emscripten_promise_reject__deps : [ '$promiseMap' ] ,
1102+ emscripten_promise_reject__sig : 'vip' ,
1103+ emscripten_promise_reject : function ( id ) {
1104+ #if RUNTIME_DEBUG
1105+ dbg ( 'emscripten_promise_reject: ' + id ) ;
1106+ #endif
1107+ assert ( promiseMap . has ( id ) ) ;
1108+ promiseMap . get ( id ) . reject ( ) ;
1109+ } ,
1110+
1111+ // Called on the main thread to syncronize the code loaded on all threads.
1112+ // This work happens asyncronously. The `callback` is called once this work
1113+ // is completely, passing the ctx.
1114+ _emscripten_sync_all_threads__sig : 'viii' ,
1115+ _emscripten_sync_all_threads__deps : [ '_emscripten_proxy_sync_code' , '$newNativePromise' ] ,
1116+ _emscripten_sync_all_threads : function ( caller , callback , ctx ) {
1117+ #if PTHREADS_DEBUG
1118+ dbg ( "_emscripten_sync_all_threads caller=" + ptrToString ( caller ) ) ;
1119+ #endif
1120+ #if ASSERTIONS
1121+ assert ( ! ENVIRONMENT_IS_PTHREAD , 'Internal Error! _emscripten_sync_all_threads() can only ever be called from main thread' ) ;
1122+ #endif
1123+
1124+ let promises = [ ] ;
1125+
1126+ // This first promise resolves once the main thread has loaded all module
1127+ promises . push ( newNativePromise ( __emscripten_thread_sync_code_async , [ 0 ] ) ) ;
1128+
1129+ // We then create a sequence of promises, one per thread, that resolve once
1130+ // each thread has performed its sync using _emscripten_proxy_sync_code.
1131+ for ( const ptr of Object . keys ( PThread . pthreads ) ) {
1132+ const pthread_ptr = Number ( ptr ) ;
1133+ if ( pthread_ptr !== caller ) {
1134+ promises . push ( newNativePromise ( __emscripten_proxy_sync_code , [ pthread_ptr ] ) ) ;
1135+ }
1136+ }
1137+
1138+ // Once all promises are resolved then we we know all threads are in
1139+ // sync and we can call the callback.
1140+ Promise . all ( promises ) . then ( ( ) => {
1141+ #if PTHREADS_DEBUG
1142+ dbg ( "_emscripten_sync_all_threads done: calling callback" ) ;
1143+ #endif
1144+ { { { makeDynCall ( 'vp' , 'callback' ) } } } ( ctx ) ;
1145+ } ) ;
1146+ } ,
1147+ #endif
1148+
10721149 $executeNotifiedProxyingQueue : function ( queue ) {
10731150 // Set the notification state to processing.
10741151 Atomics . store ( HEAP32 , queue >> 2 , { { { cDefine ( 'NOTIFICATION_RECEIVED' ) } } } ) ;
0 commit comments