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+
565580static 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
727748ZEND_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
738765ZEND_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
749782ZEND_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