Skip to content

Commit 29e0cd6

Browse files
committed
% Refactoring the coroutine context state for switching, so that the main coroutine can correctly return control.
1 parent 2896aec commit 29e0cd6

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

Zend/zend_async_API.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ ZEND_API zend_string* zend_coroutine_gen_info(zend_coroutine_t *coroutine, char
298298
zend_coroutine_name = "";
299299
}
300300

301-
if (coroutine->waker != NULL) {
301+
if (ZEND_COROUTINE_SUSPENDED(coroutine)) {
302302
return zend_strpprintf(0,
303303
"Coroutine spawned at %s:%d, suspended at %s:%d (%s)",
304304
coroutine->filename ? ZSTR_VAL(coroutine->filename) : "",

Zend/zend_async_API.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ typedef int zend_socket_t;
8181
* If type==4, output will be saved to a memory buffer (shell_exec)
8282
*/
8383
typedef enum {
84-
ZEND_ASYNC_EXEC_MODE_EXEC = 0,
85-
ZEND_ASYNC_EXEC_MODE_SYSTEM = 1,
86-
ZEND_ASYNC_EXEC_MODE_EXEC_ARRAY = 2,
87-
ZEND_ASYNC_EXEC_MODE_PASSTHRU = 3,
88-
ZEND_ASYNC_EXEC_MODE_SHELL_EXEC = 4
84+
ZEND_ASYNC_EXEC_MODE_EXEC,
85+
ZEND_ASYNC_EXEC_MODE_SYSTEM,
86+
ZEND_ASYNC_EXEC_MODE_EXEC_ARRAY,
87+
ZEND_ASYNC_EXEC_MODE_PASSTHRU,
88+
ZEND_ASYNC_EXEC_MODE_SHELL_EXEC
8989
} zend_async_exec_mode;
9090

9191
typedef enum
@@ -624,10 +624,11 @@ zend_async_scope_free_children(zend_async_scope_t *parent_scope)
624624
typedef void (*zend_async_waker_dtor)(zend_coroutine_t *coroutine);
625625

626626
typedef enum {
627-
ZEND_ASYNC_WAKER_NO_STATUS = 0,
628-
ZEND_ASYNC_WAKER_WAITING = 1,
629-
ZEND_ASYNC_WAKER_QUEUED = 2,
630-
ZEND_ASYNC_WAKER_IGNORED = 3
627+
ZEND_ASYNC_WAKER_NO_STATUS,
628+
ZEND_ASYNC_WAKER_WAITING,
629+
ZEND_ASYNC_WAKER_QUEUED,
630+
ZEND_ASYNC_WAKER_IGNORED,
631+
ZEND_ASYNC_WAKER_RESULT
631632
} ZEND_ASYNC_WAKER_STATUS;
632633

633634
struct _zend_async_waker_s {
@@ -649,6 +650,8 @@ struct _zend_async_waker_s {
649650
zend_async_waker_dtor dtor;
650651
};
651652

653+
#define ZEND_ASYNC_WAKER_WAITING(waker) ((waker)->status < ZEND_ASYNC_WAKER_RESULT)
654+
652655
/**
653656
* Coroutine destructor. Called when the coroutine needs to clean up all its data.
654657
*/
@@ -690,6 +693,12 @@ struct _zend_coroutine_s {
690693
zend_async_coroutine_dispose extended_dispose;
691694
};
692695

696+
/**
697+
* The macro evaluates to TRUE if the coroutine is in a waiting state —
698+
* either waiting for events or waiting in the execution queue.
699+
*/
700+
#define ZEND_COROUTINE_SUSPENDED(coroutine) ((coroutine)->waker != NULL && ZEND_ASYNC_WAKER_WAITING((coroutine)->waker))
701+
693702
/* Coroutine flags */
694703
#define ZEND_COROUTINE_F_STARTED (1u << 10) /* coroutine is started */
695704
#define ZEND_COROUTINE_F_CANCELLED (1u << 11) /* coroutine is cancelled */
@@ -757,11 +766,11 @@ struct _zend_async_context_s {
757766
*/
758767
typedef enum {
759768
// The module is inactive.
760-
ZEND_ASYNC_OFF = 0,
769+
ZEND_ASYNC_OFF,
761770
// The module is ready for use but has not been activated yet.
762-
ZEND_ASYNC_READY = 1,
771+
ZEND_ASYNC_READY,
763772
// The module is active and can be used.
764-
ZEND_ASYNC_ACTIVE = 2
773+
ZEND_ASYNC_ACTIVE
765774
} zend_async_state_t;
766775

767776
typedef struct {

0 commit comments

Comments
 (0)