Skip to content

Commit f030333

Browse files
committed
Expose fibers API
1 parent 3baa606 commit f030333

File tree

1 file changed

+63
-8
lines changed

1 file changed

+63
-8
lines changed

Zend/zend_fibers.c

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "zend.h"
2121
#include "zend_API.h"
2222
#include "zend_ini.h"
23+
#include "zend_variables.h"
2324
#include "zend_vm.h"
2425
#include "zend_exceptions.h"
2526
#include "zend_builtin_functions.h"
@@ -624,7 +625,11 @@ static zend_always_inline void zend_fiber_delegate_transfer_result(
624625
RETURN_THROWS();
625626
}
626627

627-
RETURN_COPY_VALUE(&transfer->value);
628+
if (return_value != NULL) {
629+
RETURN_COPY_VALUE(&transfer->value);
630+
} else {
631+
zval_ptr_dtor(&transfer->value);
632+
}
628633
}
629634

630635
static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
@@ -652,7 +657,7 @@ static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
652657
return transfer;
653658
}
654659

655-
static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fiber, zval *value, bool exception)
660+
static zend_always_inline zend_fiber_transfer zend_fiber_resume_internal(zend_fiber *fiber, zval *value, bool exception)
656661
{
657662
zend_fiber *previous = EG(active_fiber);
658663

@@ -670,8 +675,10 @@ static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fibe
670675
return transfer;
671676
}
672677

673-
static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fiber, zval *value)
678+
static zend_always_inline zend_fiber_transfer zend_fiber_suspend_internal(zend_fiber *fiber, zval *value)
674679
{
680+
ZEND_ASSERT(!(fiber->flags & ZEND_FIBER_FLAG_DESTROYED));
681+
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_RUNNING || fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED);
675682
ZEND_ASSERT(fiber->caller != NULL);
676683

677684
zend_fiber_context *caller = fiber->caller;
@@ -682,6 +689,54 @@ static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fib
682689
return zend_fiber_switch_to(caller, value, false);
683690
}
684691

692+
ZEND_API zend_result zend_fiber_start(zend_fiber *fiber, zval *return_value)
693+
{
694+
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_INIT);
695+
696+
if (zend_fiber_init_context(&fiber->context, zend_ce_fiber, zend_fiber_execute, EG(fiber_stack_size)) == FAILURE) {
697+
return FAILURE;
698+
}
699+
700+
fiber->previous = &fiber->context;
701+
702+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, NULL, false);
703+
704+
zend_fiber_delegate_transfer_result(&transfer, EG(current_execute_data), return_value);
705+
706+
return SUCCESS;
707+
}
708+
709+
ZEND_API void zend_fiber_resume(zend_fiber *fiber, zval *value, zval *return_value)
710+
{
711+
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED && fiber->caller == NULL);
712+
713+
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
714+
715+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, value, /* exception */ false);
716+
717+
zend_fiber_delegate_transfer_result(&transfer, EG(current_execute_data), return_value);
718+
}
719+
720+
ZEND_API void zend_fiber_resume_exception(zend_fiber *fiber, zval *exception, zval *return_value)
721+
{
722+
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED && fiber->caller == NULL);
723+
724+
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
725+
726+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, exception, /* exception */ true);
727+
728+
zend_fiber_delegate_transfer_result(&transfer, EG(current_execute_data), return_value);
729+
}
730+
731+
ZEND_API void zend_fiber_suspend(zend_fiber *fiber, zval *value, zval *return_value)
732+
{
733+
fiber->stack_bottom->prev_execute_data = NULL;
734+
735+
zend_fiber_transfer transfer = zend_fiber_suspend_internal(fiber, value);
736+
737+
zend_fiber_delegate_transfer_result(&transfer, EG(current_execute_data), return_value);
738+
}
739+
685740
static zend_object *zend_fiber_object_create(zend_class_entry *ce)
686741
{
687742
zend_fiber *fiber = emalloc(sizeof(zend_fiber));
@@ -707,7 +762,7 @@ static void zend_fiber_object_destroy(zend_object *object)
707762

708763
fiber->flags |= ZEND_FIBER_FLAG_DESTROYED;
709764

710-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, &graceful_exit, true);
765+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, &graceful_exit, true);
711766

712767
zval_ptr_dtor(&graceful_exit);
713768

@@ -823,7 +878,7 @@ ZEND_METHOD(Fiber, start)
823878

824879
fiber->previous = &fiber->context;
825880

826-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, NULL, false);
881+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, NULL, false);
827882

828883
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
829884
}
@@ -858,7 +913,7 @@ ZEND_METHOD(Fiber, suspend)
858913

859914
fiber->stack_bottom->prev_execute_data = NULL;
860915

861-
zend_fiber_transfer transfer = zend_fiber_suspend(fiber, value);
916+
zend_fiber_transfer transfer = zend_fiber_suspend_internal(fiber, value);
862917

863918
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
864919
}
@@ -887,7 +942,7 @@ ZEND_METHOD(Fiber, resume)
887942

888943
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
889944

890-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, value, false);
945+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, value, false);
891946

892947
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
893948
}
@@ -915,7 +970,7 @@ ZEND_METHOD(Fiber, throw)
915970

916971
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
917972

918-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, exception, true);
973+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, exception, true);
919974

920975
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
921976
}

0 commit comments

Comments
 (0)