Skip to content

Commit 36823cb

Browse files
committed
Expose fibers API
1 parent 7f8465a commit 36823cb

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"
@@ -630,7 +631,11 @@ static zend_always_inline void zend_fiber_delegate_transfer_result(
630631
RETURN_THROWS();
631632
}
632633

633-
RETURN_COPY_VALUE(&transfer->value);
634+
if (return_value != NULL) {
635+
RETURN_COPY_VALUE(&transfer->value);
636+
} else {
637+
zval_ptr_dtor(&transfer->value);
638+
}
634639
}
635640

636641
static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
@@ -658,7 +663,7 @@ static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
658663
return transfer;
659664
}
660665

661-
static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fiber, zval *value, bool exception)
666+
static zend_always_inline zend_fiber_transfer zend_fiber_resume_internal(zend_fiber *fiber, zval *value, bool exception)
662667
{
663668
zend_fiber *previous = EG(active_fiber);
664669

@@ -676,8 +681,10 @@ static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fibe
676681
return transfer;
677682
}
678683

679-
static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fiber, zval *value)
684+
static zend_always_inline zend_fiber_transfer zend_fiber_suspend_internal(zend_fiber *fiber, zval *value)
680685
{
686+
ZEND_ASSERT(!(fiber->flags & ZEND_FIBER_FLAG_DESTROYED));
687+
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_RUNNING || fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED);
681688
ZEND_ASSERT(fiber->caller != NULL);
682689

683690
zend_fiber_context *caller = fiber->caller;
@@ -688,6 +695,54 @@ static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fib
688695
return zend_fiber_switch_to(caller, value, false);
689696
}
690697

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

714769
fiber->flags |= ZEND_FIBER_FLAG_DESTROYED;
715770

716-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, &graceful_exit, true);
771+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, &graceful_exit, true);
717772

718773
zval_ptr_dtor(&graceful_exit);
719774

@@ -829,7 +884,7 @@ ZEND_METHOD(Fiber, start)
829884

830885
fiber->previous = &fiber->context;
831886

832-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, NULL, false);
887+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, NULL, false);
833888

834889
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
835890
}
@@ -864,7 +919,7 @@ ZEND_METHOD(Fiber, suspend)
864919

865920
fiber->stack_bottom->prev_execute_data = NULL;
866921

867-
zend_fiber_transfer transfer = zend_fiber_suspend(fiber, value);
922+
zend_fiber_transfer transfer = zend_fiber_suspend_internal(fiber, value);
868923

869924
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
870925
}
@@ -893,7 +948,7 @@ ZEND_METHOD(Fiber, resume)
893948

894949
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
895950

896-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, value, false);
951+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, value, false);
897952

898953
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
899954
}
@@ -921,7 +976,7 @@ ZEND_METHOD(Fiber, throw)
921976

922977
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
923978

924-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, exception, true);
979+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, exception, true);
925980

926981
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
927982
}

0 commit comments

Comments
 (0)