@@ -219,6 +219,11 @@ PHP_FUNCTION(Async_await)
219219 zend_async_event_t * awaitable_event = ZEND_ASYNC_OBJECT_TO_EVENT (awaitable );
220220 zend_async_event_t * cancellation_event = cancellation != NULL ? ZEND_ASYNC_OBJECT_TO_EVENT (cancellation ) : NULL ;
221221
222+ // If the awaitable is the same as the cancellation event, we can skip the cancellation check.
223+ if (awaitable_event == cancellation_event ) {
224+ cancellation_event = NULL ;
225+ }
226+
222227 // If the awaitable is already resolved, we can return the result immediately.
223228 if (ZEND_ASYNC_EVENT_IS_CLOSED (awaitable_event )) {
224229
@@ -236,7 +241,7 @@ PHP_FUNCTION(Async_await)
236241
237242 // If the cancellation event is already resolved, we can return exception immediately.
238243 if (cancellation_event != NULL && ZEND_ASYNC_EVENT_IS_CLOSED (cancellation_event )) {
239- if (ZEND_ASYNC_EVENT_EXTRACT_RESULT (awaitable_event , return_value )) {
244+ if (ZEND_ASYNC_EVENT_EXTRACT_RESULT (cancellation_event , return_value )) {
240245 return ;
241246 }
242247
@@ -721,10 +726,12 @@ PHP_FUNCTION(Async_rootContext)
721726 THROW_IF_ASYNC_OFF ;
722727 THROW_IF_SCHEDULER_CONTEXT ;
723728
724- /* TODO: Implement root context access */
725- /* For now, return a new context */
726- async_context_t * context = async_context_new ();
727- RETURN_OBJ (& context -> std );
729+ if (ASYNC_G (root_context ) == NULL ) {
730+ ASYNC_G (root_context ) = (zend_async_context_t * )async_context_new ();
731+ }
732+
733+ async_context_t * context = (async_context_t * )ASYNC_G (root_context );
734+ RETURN_OBJ_COPY (& context -> std );
728735}
729736
730737PHP_FUNCTION (Async_getCoroutines )
@@ -755,7 +762,7 @@ PHP_FUNCTION(Async_gracefulShutdown)
755762 THROW_IF_ASYNC_OFF ;
756763 THROW_IF_SCHEDULER_CONTEXT ;
757764
758- /* TODO: Implement graceful shutdown */
765+ ZEND_ASYNC_SHUTDOWN ();
759766}
760767
761768/*
@@ -898,6 +905,9 @@ static PHP_GINIT_FUNCTION(async)
898905 async_globals -> signal_handlers = NULL ;
899906 async_globals -> signal_events = NULL ;
900907 async_globals -> process_events = NULL ;
908+ async_globals -> root_context = NULL ;
909+ /* Maximum number of coroutines in the concurrent iterator */
910+ async_globals -> default_concurrency = 32 ;
901911
902912#ifdef PHP_WIN32
903913 async_globals -> watcherThread = NULL ;
0 commit comments