Skip to content

Commit 8fe1db2

Browse files
committed
Delay fiber VM stack cleanup until after observer has been called
Signed-off-by: Bob Weinand <[email protected]>
1 parent 2f9bc6e commit 8fe1db2

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

Zend/zend_fibers.c

+20-5
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,10 @@ ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context)
360360
{
361361
zend_observer_fiber_destroy_notify(context);
362362

363+
if (context->cleanup) {
364+
context->cleanup(context);
365+
}
366+
363367
zend_fiber_stack_free(context->stack);
364368
}
365369

@@ -441,6 +445,19 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer)
441445
}
442446
}
443447

448+
static void zend_fiber_cleanup(zend_fiber_context *context)
449+
{
450+
zend_fiber *fiber = zend_fiber_from_context(context);
451+
452+
zend_vm_stack current_stack = EG(vm_stack);
453+
EG(vm_stack) = fiber->vm_stack;
454+
zend_vm_stack_destroy();
455+
EG(vm_stack) = current_stack;
456+
fiber->execute_data = NULL;
457+
fiber->stack_bottom = NULL;
458+
fiber->caller = NULL;
459+
}
460+
444461
static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer)
445462
{
446463
ZEND_ASSERT(Z_TYPE(transfer->value) == IS_NULL && "Initial transfer value to fiber context must be NULL");
@@ -501,12 +518,10 @@ static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer)
501518
transfer->flags = ZEND_FIBER_TRANSFER_FLAG_BAILOUT;
502519
} zend_end_try();
503520

504-
transfer->context = fiber->caller;
521+
fiber->context.cleanup = &zend_fiber_cleanup;
522+
fiber->vm_stack = EG(vm_stack);
505523

506-
zend_vm_stack_destroy();
507-
fiber->execute_data = NULL;
508-
fiber->stack_bottom = NULL;
509-
fiber->caller = NULL;
524+
transfer->context = fiber->caller;
510525
}
511526

512527
/* Handles forwarding of result / error from a transfer into the running fiber. */

Zend/zend_fibers.h

+7
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ typedef struct _zend_fiber_transfer {
7171
/* Coroutine functions must populate the given transfer with a new context
7272
* and (optional) data before they return. */
7373
typedef void (*zend_fiber_coroutine)(zend_fiber_transfer *transfer);
74+
typedef void (*zend_fiber_clean)(zend_fiber_context *context);
7475

7576
struct _zend_fiber_context {
7677
/* Pointer to boost.context or ucontext_t data. */
@@ -82,6 +83,9 @@ struct _zend_fiber_context {
8283
/* Entrypoint function of the fiber. */
8384
zend_fiber_coroutine function;
8485

86+
/* Cleanup function for fiber. */
87+
zend_fiber_clean cleanup;
88+
8589
/* Assigned C stack. */
8690
zend_fiber_stack *stack;
8791

@@ -121,6 +125,9 @@ struct _zend_fiber {
121125
/* Frame on the bottom of the fiber vm stack. */
122126
zend_execute_data *stack_bottom;
123127

128+
/* Active fiber vm stack. */
129+
zend_vm_stack vm_stack;
130+
124131
/* Storage for fiber return value. */
125132
zval result;
126133
};

0 commit comments

Comments
 (0)