32
32
#include "zend_generators.h"
33
33
34
34
#include "zend_fibers.h"
35
+
36
+ #include "zend_async_API.h"
35
37
#include "zend_fibers_arginfo.h"
36
38
37
39
#ifdef HAVE_VALGRIND
@@ -562,6 +564,19 @@ static void zend_fiber_cleanup(zend_fiber_context *context)
562
564
fiber -> caller = NULL ;
563
565
}
564
566
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
+
565
580
static ZEND_STACK_ALIGNED void zend_fiber_execute (zend_fiber_transfer * transfer )
566
581
{
567
582
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)
711
726
{
712
727
ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_INIT );
713
728
729
+ #ifdef PHP_ASYNC_API
730
+ if (UNEXPECTED (false == can_use_fiber ())) {
731
+ return FAILURE ;
732
+ }
733
+ #endif
734
+
714
735
if (zend_fiber_init_context (& fiber -> context , zend_ce_fiber , zend_fiber_execute , EG (fiber_stack_size )) == FAILURE ) {
715
736
return FAILURE ;
716
737
}
@@ -726,6 +747,12 @@ ZEND_API zend_result zend_fiber_start(zend_fiber *fiber, zval *return_value)
726
747
727
748
ZEND_API void zend_fiber_resume (zend_fiber * fiber , zval * value , zval * return_value )
728
749
{
750
+ #ifdef PHP_ASYNC_API
751
+ if (UNEXPECTED (false == can_use_fiber ())) {
752
+ return ;
753
+ }
754
+ #endif
755
+
729
756
ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
730
757
731
758
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
737
764
738
765
ZEND_API void zend_fiber_resume_exception (zend_fiber * fiber , zval * exception , zval * return_value )
739
766
{
767
+ #ifdef PHP_ASYNC_API
768
+ if (UNEXPECTED (false == can_use_fiber ())) {
769
+ return ;
770
+ }
771
+ #endif
772
+
740
773
ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
741
774
742
775
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
748
781
749
782
ZEND_API void zend_fiber_suspend (zend_fiber * fiber , zval * value , zval * return_value )
750
783
{
784
+ #ifdef PHP_ASYNC_API
785
+ if (UNEXPECTED (false == can_use_fiber ())) {
786
+ return ;
787
+ }
788
+ #endif
789
+
751
790
fiber -> stack_bottom -> prev_execute_data = NULL ;
752
791
753
792
zend_fiber_transfer transfer = zend_fiber_suspend_internal (fiber , value );
@@ -876,6 +915,12 @@ ZEND_METHOD(Fiber, __construct)
876
915
Z_PARAM_FUNC (fci , fcc )
877
916
ZEND_PARSE_PARAMETERS_END ();
878
917
918
+ #ifdef PHP_ASYNC_API
919
+ if (UNEXPECTED (false == can_use_fiber ())) {
920
+ RETURN_THROWS ();
921
+ }
922
+ #endif
923
+
879
924
zend_fiber * fiber = (zend_fiber * ) Z_OBJ_P (ZEND_THIS );
880
925
881
926
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)
898
943
Z_PARAM_VARIADIC_WITH_NAMED (fiber -> fci .params , fiber -> fci .param_count , fiber -> fci .named_params );
899
944
ZEND_PARSE_PARAMETERS_END ();
900
945
946
+ #ifdef PHP_ASYNC_API
947
+ if (UNEXPECTED (false == can_use_fiber ())) {
948
+ RETURN_THROWS ();
949
+ }
950
+ #endif
951
+
901
952
if (UNEXPECTED (zend_fiber_switch_blocked ())) {
902
953
zend_throw_error (zend_ce_fiber_error , "Cannot switch fibers in current execution context" );
903
954
RETURN_THROWS ();
0 commit comments