@@ -95,7 +95,7 @@ impl<UserMacroTask> RuntimeHostHooks<UserMacroTask> {
9595 }
9696
9797 pub fn any_pending_macro_tasks ( & self ) -> bool {
98- self . host_data . macro_task_count . load ( Ordering :: Relaxed ) > 0
98+ self . host_data . macro_task_count . load ( Ordering :: Acquire ) > 0
9999 }
100100
101101 /// Resolve a module specifier relative to a referrer path
@@ -784,12 +784,20 @@ impl<UserMacroTask> Runtime<UserMacroTask> {
784784 } ) ;
785785 }
786786
787- // If both the microtasks and macrotasks queues are empty we can end the event loop
788- if !self . host_hooks . any_pending_macro_tasks ( ) {
787+ // Try to handle a macro task without blocking
788+ // This handles the case where a task completed so fast that the counter
789+ // was already decremented but the message is still in the channel
790+ let has_macro_task = self . try_handle_macro_task ( ) ;
791+
792+ // Only exit if there are no pending tasks AND no message was processed
793+ if !has_macro_task && !self . host_hooks . any_pending_macro_tasks ( ) {
789794 break ;
790795 }
791-
792- self . handle_macro_task ( ) ;
796+
797+ // If we saw pending tasks but got no message, block waiting for one
798+ if !has_macro_task && self . host_hooks . any_pending_macro_tasks ( ) {
799+ self . handle_macro_task ( ) ;
800+ }
793801 }
794802
795803 RuntimeOutput {
@@ -825,6 +833,35 @@ impl<UserMacroTask> Runtime<UserMacroTask> {
825833 _ => { }
826834 }
827835 }
836+
837+ // Try to handle a macro task without blocking, returns true if a task was handled
838+ pub fn try_handle_macro_task ( & mut self ) -> bool {
839+ match self . config . macro_task_rx . try_recv ( ) {
840+ Ok ( MacroTask :: ResolvePromise ( root_value) ) => {
841+ self . agent . run_in_realm ( & self . realm_root , |agent, gc| {
842+ let value = root_value. take ( agent) ;
843+ if let Value :: Promise ( promise) = value {
844+ let promise_capability = PromiseCapability :: from_promise ( promise, false ) ;
845+ promise_capability. resolve ( agent, Value :: Undefined , gc) ;
846+ } else {
847+ panic ! ( "Attempted to resolve a non-promise value" ) ;
848+ }
849+ } ) ;
850+ true
851+ }
852+ // Let the user runtime handle its macro tasks
853+ Ok ( MacroTask :: User ( e) ) => {
854+ ( self . config . eventloop_handler ) (
855+ e,
856+ & mut self . agent ,
857+ & self . realm_root ,
858+ & self . host_hooks . host_data ,
859+ ) ;
860+ true
861+ }
862+ _ => false
863+ }
864+ }
828865}
829866
830867pub struct RuntimeOutput {
0 commit comments