Skip to content

Commit 7c6ff87

Browse files
committed
Expose fibers API
1 parent 6b03720 commit 7c6ff87

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"
@@ -637,7 +638,11 @@ static zend_always_inline void zend_fiber_delegate_transfer_result(
637638
RETURN_THROWS();
638639
}
639640

640-
RETURN_COPY_VALUE(&transfer->value);
641+
if (return_value != NULL) {
642+
RETURN_COPY_VALUE(&transfer->value);
643+
} else {
644+
zval_ptr_dtor(&transfer->value);
645+
}
641646
}
642647

643648
static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
@@ -665,7 +670,7 @@ static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
665670
return transfer;
666671
}
667672

668-
static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fiber, zval *value, bool exception)
673+
static zend_always_inline zend_fiber_transfer zend_fiber_resume_internal(zend_fiber *fiber, zval *value, bool exception)
669674
{
670675
zend_fiber *previous = EG(active_fiber);
671676

@@ -683,8 +688,10 @@ static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fibe
683688
return transfer;
684689
}
685690

686-
static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fiber, zval *value)
691+
static zend_always_inline zend_fiber_transfer zend_fiber_suspend_internal(zend_fiber *fiber, zval *value)
687692
{
693+
ZEND_ASSERT(!(fiber->flags & ZEND_FIBER_FLAG_DESTROYED));
694+
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_RUNNING || fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED);
688695
ZEND_ASSERT(fiber->caller != NULL);
689696

690697
zend_fiber_context *caller = fiber->caller;
@@ -695,6 +702,54 @@ static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fib
695702
return zend_fiber_switch_to(caller, value, false);
696703
}
697704

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

721776
fiber->flags |= ZEND_FIBER_FLAG_DESTROYED;
722777

723-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, &graceful_exit, true);
778+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, &graceful_exit, true);
724779

725780
zval_ptr_dtor(&graceful_exit);
726781

@@ -836,7 +891,7 @@ ZEND_METHOD(Fiber, start)
836891

837892
fiber->previous = &fiber->context;
838893

839-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, NULL, false);
894+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, NULL, false);
840895

841896
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
842897
}
@@ -871,7 +926,7 @@ ZEND_METHOD(Fiber, suspend)
871926

872927
fiber->stack_bottom->prev_execute_data = NULL;
873928

874-
zend_fiber_transfer transfer = zend_fiber_suspend(fiber, value);
929+
zend_fiber_transfer transfer = zend_fiber_suspend_internal(fiber, value);
875930

876931
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
877932
}
@@ -900,7 +955,7 @@ ZEND_METHOD(Fiber, resume)
900955

901956
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
902957

903-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, value, false);
958+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, value, false);
904959

905960
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
906961
}
@@ -928,7 +983,7 @@ ZEND_METHOD(Fiber, throw)
928983

929984
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
930985

931-
zend_fiber_transfer transfer = zend_fiber_resume(fiber, exception, true);
986+
zend_fiber_transfer transfer = zend_fiber_resume_internal(fiber, exception, true);
932987

933988
zend_fiber_delegate_transfer_result(&transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
934989
}

0 commit comments

Comments
 (0)