@@ -2176,11 +2176,21 @@ ZEND_API int zend_gc_collect_cycles(void)
2176
2176
return 0 ;
2177
2177
}
2178
2178
2179
+ const bool in_fiber = EG (active_fiber ) != NULL ;
2180
+
2179
2181
//
2180
2182
// We might enter this context from different coroutines, so we don’t initialize anything here.
2181
2183
//
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
+ }
2184
2194
2185
2195
if (UNEXPECTED (context -> state == GC_ASYNC_STATE_CONTINUE )) {
2186
2196
// 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)
2197
2207
context -> should_rerun_gc = 0 ;
2198
2208
context -> did_rerun_gc = 0 ;
2199
2209
context -> gc_flags = 0 ;
2210
+ // reset the destructor index
2211
+ GC_G (dtor_idx ) = GC_FIRST_ROOT ;
2200
2212
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 {
2203
2223
stack -> prev = NULL ;
2204
2224
stack -> next = NULL ;
2205
- GC_G (gc_stack ) = stack ;
2206
- } else {
2207
- stack = GC_G (gc_stack );
2208
2225
}
2209
2226
}
2210
2227
@@ -2357,7 +2374,9 @@ ZEND_API int zend_gc_collect_cycles(void)
2357
2374
gc_stack_free (GC_COLLECT_STACK );
2358
2375
2359
2376
#ifdef PHP_ASYNC_API
2360
- end = GC_G (first_unused );
2377
+ if (false == in_fiber ) {
2378
+ end = GC_G (first_unused );
2379
+ }
2361
2380
#endif
2362
2381
2363
2382
/* Destroy zvals. The root buffer may be reallocated. */
@@ -2442,9 +2461,15 @@ ZEND_API int zend_gc_collect_cycles(void)
2442
2461
2443
2462
GC_G (collector_time ) += zend_hrtime () - GC_COLLECT_START_TIME ;
2444
2463
#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
+ }
2448
2473
}
2449
2474
#endif
2450
2475
return GC_COLLECT_TOTAL_COUNT ;
0 commit comments