@@ -624,7 +624,6 @@ struct _zend_async_task_s {
624
624
625
625
typedef void (* zend_async_before_coroutine_enqueue_t )(zend_coroutine_t * coroutine , zend_async_scope_t * scope , zval * result );
626
626
typedef void (* zend_async_after_coroutine_enqueue_t )(zend_coroutine_t * coroutine , zend_async_scope_t * scope );
627
- typedef void (* zend_async_scope_dispose_t )(zend_async_scope_t * scope );
628
627
629
628
/* Dynamic array of async event callbacks */
630
629
typedef struct _zend_async_scopes_vector_s {
@@ -641,13 +640,12 @@ typedef struct _zend_async_scopes_vector_s {
641
640
* it initiates the disposal process of the Scope.
642
641
*
643
642
* However, the internal Scope structure remains in memory until the last coroutine has completed.
644
- *
645
643
*/
646
644
struct _zend_async_scope_s {
647
- /* The scope ZEND_ASYNC_SCOPE_F flags */
648
- uint32_t flags ;
645
+ /* Event object for reacting to events. */
646
+ zend_async_event_t event ;
649
647
/* The link to the zend_object structure */
650
- zend_object * scope_object ;
648
+ zend_object * scope_object ;
651
649
652
650
zend_async_scopes_vector_t scopes ;
653
651
zend_async_scope_t * parent_scope ;
@@ -656,25 +654,29 @@ struct _zend_async_scope_s {
656
654
657
655
zend_async_before_coroutine_enqueue_t before_coroutine_enqueue ;
658
656
zend_async_after_coroutine_enqueue_t after_coroutine_enqueue ;
659
- zend_async_scope_dispose_t dispose ;
657
+ void ( * cancel )( zend_async_scope_t * scope , zend_object * error , bool transfer_error , const bool is_safely ) ;
660
658
};
661
659
662
- #define ZEND_ASYNC_SCOPE_F_CLOSED (1u << 0) /* scope was closed */
663
- #define ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY (1u << 1) /* scope will not free memory in dispose handler */
664
- #define ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY (1u << 2) /* scope will be disposed safely */
660
+ #define ZEND_ASYNC_SCOPE_F_CLOSED ZEND_ASYNC_EVENT_F_CLOSED /* scope was closed */
661
+ #define ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY ZEND_ASYNC_EVENT_F_NO_FREE_MEMORY /* scope will not free memory in dispose handler */
662
+ #define ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY (1u << 14) /* scope will be disposed safely */
663
+ #define ZEND_ASYNC_SCOPE_F_CANCELLED (1u << 15) /* scope was cancelled */
664
+
665
+ #define ZEND_ASYNC_SCOPE_IS_CLOSED (scope ) (((scope)->event.flags & ZEND_ASYNC_SCOPE_F_CLOSED) != 0)
666
+ #define ZEND_ASYNC_SCOPE_IS_NO_FREE_MEMORY (scope ) (((scope)->event.flags & ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY) != 0)
667
+ #define ZEND_ASYNC_SCOPE_IS_DISPOSE_SAFELY (scope ) (((scope)->event.flags & ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY) != 0)
668
+ #define ZEND_ASYNC_SCOPE_IS_CANCELLED (scope ) (((scope)->event.flags & ZEND_ASYNC_SCOPE_F_CANCELLED) != 0)
665
669
666
- #define ZEND_ASYNC_SCOPE_IS_CLOSED (scope ) (((scope)->flags & ZEND_ASYNC_SCOPE_F_CLOSED) != 0)
667
- #define ZEND_ASYNC_SCOPE_IS_NO_FREE_MEMORY (scope ) (((scope)->flags & ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY) != 0)
668
- #define ZEND_ASYNC_SCOPE_IS_DISPOSE_SAFELY (scope ) (((scope)->flags & ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY) != 0)
670
+ #define ZEND_ASYNC_SCOPE_SET_CLOSED (scope ) ((scope)->event.flags |= ZEND_ASYNC_SCOPE_F_CLOSED)
671
+ #define ZEND_ASYNC_SCOPE_CLR_CLOSED (scope ) ((scope)->event.flags &= ~ZEND_ASYNC_SCOPE_F_CLOSED)
669
672
670
- #define ZEND_ASYNC_SCOPE_SET_CLOSED (scope ) ((scope)->flags |= ZEND_ASYNC_SCOPE_F_CLOSED )
671
- #define ZEND_ASYNC_SCOPE_CLR_CLOSED (scope ) ((scope)->flags &= ~ZEND_ASYNC_SCOPE_F_CLOSED )
673
+ #define ZEND_ASYNC_SCOPE_SET_NO_FREE_MEMORY (scope ) ((scope)->event. flags |= ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY )
674
+ #define ZEND_ASYNC_SCOPE_CLR_NO_FREE_MEMORY (scope ) ((scope)->event. flags &= ~ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY )
672
675
673
- #define ZEND_ASYNC_SCOPE_SET_NO_FREE_MEMORY (scope ) ((scope)->flags |= ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY )
674
- #define ZEND_ASYNC_SCOPE_CLR_NO_FREE_MEMORY (scope ) ((scope)->flags &= ~ZEND_ASYNC_SCOPE_F_NO_FREE_MEMORY )
676
+ #define ZEND_ASYNC_SCOPE_SET_DISPOSE_SAFELY (scope ) ((scope)->event. flags |= ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY )
677
+ #define ZEND_ASYNC_SCOPE_CLR_DISPOSE_SAFELY (scope ) ((scope)->event. flags &= ~ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY )
675
678
676
- #define ZEND_ASYNC_SCOPE_SET_DISPOSE (scope ) ((scope)->flags |= ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY)
677
- #define ZEND_ASYNC_SCOPE_CLR_DISPOSE (scope ) ((scope)->flags &= ~ZEND_ASYNC_SCOPE_F_DISPOSE_SAFELY)
679
+ #define ZEND_ASYNC_SCOPE_SET_CANCELLED (scope ) ((scope)->event.flags |= ZEND_ASYNC_SCOPE_F_CANCELLED)
678
680
679
681
static zend_always_inline void
680
682
zend_async_scope_add_child (zend_async_scope_t * parent_scope , zend_async_scope_t * child_scope )
@@ -862,6 +864,28 @@ static zend_always_inline zend_string *zend_coroutine_callable_name(const zend_c
862
864
return zend_string_init ("internal function" , sizeof ("internal function" ) - 1 , 0 );
863
865
}
864
866
867
+ /**
868
+ * Macro for constructing an FCALL structure from PHP function parameters.
869
+ * Z_PARAM_FUNC(fci, fcc);
870
+ * Z_PARAM_VARIADIC_WITH_NAMED(args, args_count, named_args);
871
+ */
872
+ #define ZEND_ASYNC_FCALL_DEFINE (fcall , fci , fcc , args , args_count , named_args ) \
873
+ zend_fcall_t * fcall = ecalloc(1, sizeof(zend_fcall_t)); \
874
+ fcall->fci = fci; \
875
+ fcall->fci_cache = fcc; \
876
+ if (args_count) { \
877
+ fcall->fci.param_count = args_count; \
878
+ fcall->fci.params = safe_emalloc(args_count, sizeof(zval), 0); \
879
+ for (uint32_t i = 0; i < args_count; i++) { \
880
+ ZVAL_COPY(&fcall->fci.params[i], &args[i]); \
881
+ } \
882
+ } \
883
+ if (named_args) { \
884
+ fcall->fci.named_params = named_args; \
885
+ GC_ADDREF(named_args); \
886
+ } \
887
+ Z_TRY_ADDREF(fcall->fci.function_name);
888
+
865
889
///////////////////////////////////////////////////////////////
866
890
/// Async Context Structures
867
891
///////////////////////////////////////////////////////////////
0 commit comments