mirror of
https://github.com/php/php-src.git
synced 2024-11-27 03:44:07 +08:00
Delay fiber VM stack cleanup until after observer has been called
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
This commit is contained in:
parent
2f9bc6e37a
commit
8fe1db2089
@ -360,6 +360,10 @@ ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context)
|
||||
{
|
||||
zend_observer_fiber_destroy_notify(context);
|
||||
|
||||
if (context->cleanup) {
|
||||
context->cleanup(context);
|
||||
}
|
||||
|
||||
zend_fiber_stack_free(context->stack);
|
||||
}
|
||||
|
||||
@ -441,6 +445,19 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer)
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_fiber_cleanup(zend_fiber_context *context)
|
||||
{
|
||||
zend_fiber *fiber = zend_fiber_from_context(context);
|
||||
|
||||
zend_vm_stack current_stack = EG(vm_stack);
|
||||
EG(vm_stack) = fiber->vm_stack;
|
||||
zend_vm_stack_destroy();
|
||||
EG(vm_stack) = current_stack;
|
||||
fiber->execute_data = NULL;
|
||||
fiber->stack_bottom = NULL;
|
||||
fiber->caller = NULL;
|
||||
}
|
||||
|
||||
static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer)
|
||||
{
|
||||
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)
|
||||
transfer->flags = ZEND_FIBER_TRANSFER_FLAG_BAILOUT;
|
||||
} zend_end_try();
|
||||
|
||||
transfer->context = fiber->caller;
|
||||
fiber->context.cleanup = &zend_fiber_cleanup;
|
||||
fiber->vm_stack = EG(vm_stack);
|
||||
|
||||
zend_vm_stack_destroy();
|
||||
fiber->execute_data = NULL;
|
||||
fiber->stack_bottom = NULL;
|
||||
fiber->caller = NULL;
|
||||
transfer->context = fiber->caller;
|
||||
}
|
||||
|
||||
/* Handles forwarding of result / error from a transfer into the running fiber. */
|
||||
|
@ -71,6 +71,7 @@ typedef struct _zend_fiber_transfer {
|
||||
/* Coroutine functions must populate the given transfer with a new context
|
||||
* and (optional) data before they return. */
|
||||
typedef void (*zend_fiber_coroutine)(zend_fiber_transfer *transfer);
|
||||
typedef void (*zend_fiber_clean)(zend_fiber_context *context);
|
||||
|
||||
struct _zend_fiber_context {
|
||||
/* Pointer to boost.context or ucontext_t data. */
|
||||
@ -82,6 +83,9 @@ struct _zend_fiber_context {
|
||||
/* Entrypoint function of the fiber. */
|
||||
zend_fiber_coroutine function;
|
||||
|
||||
/* Cleanup function for fiber. */
|
||||
zend_fiber_clean cleanup;
|
||||
|
||||
/* Assigned C stack. */
|
||||
zend_fiber_stack *stack;
|
||||
|
||||
@ -121,6 +125,9 @@ struct _zend_fiber {
|
||||
/* Frame on the bottom of the fiber vm stack. */
|
||||
zend_execute_data *stack_bottom;
|
||||
|
||||
/* Active fiber vm stack. */
|
||||
zend_vm_stack vm_stack;
|
||||
|
||||
/* Storage for fiber return value. */
|
||||
zval result;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user