@@ -2176,11 +2176,21 @@ ZEND_API int zend_gc_collect_cycles(void)
21762176 return 0 ;
21772177 }
21782178
2179+ const bool in_fiber = EG (active_fiber ) != NULL ;
2180+
21792181 //
21802182 // We might enter this context from different coroutines, so we don’t initialize anything here.
21812183 //
2182- gc_async_context_t * context = & GC_G (async_context );
2183- gc_stack * stack = GC_G (gc_stack );
2184+ gc_async_context_t * context = NULL ;
2185+ gc_stack * stack = NULL ;
2186+
2187+ if (in_fiber ) {
2188+ context = emalloc (sizeof (gc_async_context_t ));
2189+ stack = emalloc (sizeof (gc_stack ));
2190+ } else {
2191+ context = & GC_G (async_context );
2192+ stack = GC_G (gc_stack );
2193+ }
21842194
21852195 if (UNEXPECTED (context -> state == GC_ASYNC_STATE_CONTINUE )) {
21862196 // If we reach this point, it means the destructor call was interrupted by a suspend() operation,
@@ -2197,14 +2207,21 @@ ZEND_API int zend_gc_collect_cycles(void)
21972207 context -> should_rerun_gc = 0 ;
21982208 context -> did_rerun_gc = 0 ;
21992209 context -> gc_flags = 0 ;
2210+ // reset the destructor index
2211+ GC_G (dtor_idx ) = GC_FIRST_ROOT ;
22002212
2201- if (GC_G (gc_stack ) == NULL ) {
2202- stack = ecalloc (1 , sizeof (gc_stack ));
2213+ if (false == in_fiber ) {
2214+ if (GC_G (gc_stack ) == NULL ) {
2215+ stack = emalloc (sizeof (gc_stack ));
2216+ stack -> prev = NULL ;
2217+ stack -> next = NULL ;
2218+ GC_G (gc_stack ) = stack ;
2219+ } else {
2220+ stack = GC_G (gc_stack );
2221+ }
2222+ } else {
22032223 stack -> prev = NULL ;
22042224 stack -> next = NULL ;
2205- GC_G (gc_stack ) = stack ;
2206- } else {
2207- stack = GC_G (gc_stack );
22082225 }
22092226 }
22102227
@@ -2357,7 +2374,9 @@ ZEND_API int zend_gc_collect_cycles(void)
23572374 gc_stack_free (GC_COLLECT_STACK );
23582375
23592376#ifdef PHP_ASYNC_API
2360- end = GC_G (first_unused );
2377+ if (false == in_fiber ) {
2378+ end = GC_G (first_unused );
2379+ }
23612380#endif
23622381
23632382 /* Destroy zvals. The root buffer may be reallocated. */
@@ -2442,9 +2461,15 @@ ZEND_API int zend_gc_collect_cycles(void)
24422461
24432462 GC_G (collector_time ) += zend_hrtime () - GC_COLLECT_START_TIME ;
24442463#ifdef PHP_ASYNC_API
2445- GC_G (async_context ).state = GC_ASYNC_STATE_NONE ;
2446- if (GC_G (gc_stack ) != NULL ) {
2447- GC_COLLECT_FREE_STACK ;
2464+ if (in_fiber ) {
2465+ efree (context );
2466+ gc_stack_free (stack );
2467+ efree (stack );
2468+ } else {
2469+ GC_G (async_context ).state = GC_ASYNC_STATE_NONE ;
2470+ if (GC_G (gc_stack ) != NULL ) {
2471+ GC_COLLECT_FREE_STACK ;
2472+ }
24482473 }
24492474#endif
24502475 return GC_COLLECT_TOTAL_COUNT ;
0 commit comments