Skip to content

Commit 6b98adb

Browse files
committed
#23: + edge cases for fiber from spawn and spawn from fiber
1 parent 2920783 commit 6b98adb

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

Zend/zend_fibers.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "zend_generators.h"
3333

3434
#include "zend_fibers.h"
35+
36+
#include "zend_async_API.h"
3537
#include "zend_fibers_arginfo.h"
3638

3739
#ifdef HAVE_VALGRIND
@@ -562,6 +564,19 @@ static void zend_fiber_cleanup(zend_fiber_context *context)
562564
fiber->caller = NULL;
563565
}
564566

567+
#ifdef PHP_ASYNC_API
568+
static zend_always_inline bool can_use_fiber(void)
569+
{
570+
if (UNEXPECTED(ZEND_ASYNC_IS_ACTIVE)) {
571+
zend_throw_error(zend_ce_fiber_error, "Cannot create a fiber while an True Async is active");
572+
return false;
573+
}
574+
575+
ZEND_ASYNC_DEACTIVATE;
576+
return true;
577+
}
578+
#endif
579+
565580
static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer)
566581
{
567582
ZEND_ASSERT(Z_TYPE(transfer->value) == IS_NULL && "Initial transfer value to fiber context must be NULL");
@@ -711,6 +726,12 @@ ZEND_API zend_result zend_fiber_start(zend_fiber *fiber, zval *return_value)
711726
{
712727
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_INIT);
713728

729+
#ifdef PHP_ASYNC_API
730+
if (UNEXPECTED(false == can_use_fiber())) {
731+
return FAILURE;
732+
}
733+
#endif
734+
714735
if (zend_fiber_init_context(&fiber->context, zend_ce_fiber, zend_fiber_execute, EG(fiber_stack_size)) == FAILURE) {
715736
return FAILURE;
716737
}
@@ -726,6 +747,12 @@ ZEND_API zend_result zend_fiber_start(zend_fiber *fiber, zval *return_value)
726747

727748
ZEND_API void zend_fiber_resume(zend_fiber *fiber, zval *value, zval *return_value)
728749
{
750+
#ifdef PHP_ASYNC_API
751+
if (UNEXPECTED(false == can_use_fiber())) {
752+
return;
753+
}
754+
#endif
755+
729756
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED && fiber->caller == NULL);
730757

731758
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
@@ -737,6 +764,12 @@ ZEND_API void zend_fiber_resume(zend_fiber *fiber, zval *value, zval *return_val
737764

738765
ZEND_API void zend_fiber_resume_exception(zend_fiber *fiber, zval *exception, zval *return_value)
739766
{
767+
#ifdef PHP_ASYNC_API
768+
if (UNEXPECTED(false == can_use_fiber())) {
769+
return;
770+
}
771+
#endif
772+
740773
ZEND_ASSERT(fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED && fiber->caller == NULL);
741774

742775
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
@@ -748,6 +781,12 @@ ZEND_API void zend_fiber_resume_exception(zend_fiber *fiber, zval *exception, zv
748781

749782
ZEND_API void zend_fiber_suspend(zend_fiber *fiber, zval *value, zval *return_value)
750783
{
784+
#ifdef PHP_ASYNC_API
785+
if (UNEXPECTED(false == can_use_fiber())) {
786+
return;
787+
}
788+
#endif
789+
751790
fiber->stack_bottom->prev_execute_data = NULL;
752791

753792
zend_fiber_transfer transfer = zend_fiber_suspend_internal(fiber, value);
@@ -876,6 +915,12 @@ ZEND_METHOD(Fiber, __construct)
876915
Z_PARAM_FUNC(fci, fcc)
877916
ZEND_PARSE_PARAMETERS_END();
878917

918+
#ifdef PHP_ASYNC_API
919+
if (UNEXPECTED(false == can_use_fiber())) {
920+
RETURN_THROWS();
921+
}
922+
#endif
923+
879924
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
880925

881926
if (UNEXPECTED(fiber->context.status != ZEND_FIBER_STATUS_INIT || Z_TYPE(fiber->fci.function_name) != IS_UNDEF)) {
@@ -898,6 +943,12 @@ ZEND_METHOD(Fiber, start)
898943
Z_PARAM_VARIADIC_WITH_NAMED(fiber->fci.params, fiber->fci.param_count, fiber->fci.named_params);
899944
ZEND_PARSE_PARAMETERS_END();
900945

946+
#ifdef PHP_ASYNC_API
947+
if (UNEXPECTED(false == can_use_fiber())) {
948+
RETURN_THROWS();
949+
}
950+
#endif
951+
901952
if (UNEXPECTED(zend_fiber_switch_blocked())) {
902953
zend_throw_error(zend_ce_fiber_error, "Cannot switch fibers in current execution context");
903954
RETURN_THROWS();

0 commit comments

Comments
 (0)