Skip to content

Commit bad113e

Browse files
committed
+ new API: ZEND_ASYNC_EV_HANDLER_REGISTER/ZEND_ASYNC_EV_HANDLER_UNREGISTER The API is designed to allow adding additional handlers to the reactor loop without modifying the reactor's code.
1 parent 2f46c0a commit bad113e

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

Zend/zend_async_API.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,3 +1602,54 @@ static void zend_async_main_handlers_shutdown(void)
16021602
vector->in_execution = false;
16031603
}
16041604
}
1605+
1606+
ZEND_API bool zend_async_ev_handler_register(const zend_async_ev_handler_fn handler)
1607+
{
1608+
if (UNEXPECTED(!ZEND_ASYNC_IS_READY)) {
1609+
zend_throw_error(NULL, "True Async is no longer in the Ready state");
1610+
return false;
1611+
}
1612+
1613+
if (UNEXPECTED(handler == NULL)) {
1614+
return false;
1615+
}
1616+
1617+
/* Check if handler already exists */
1618+
for (int i = 0; i < ZEND_ASYNC_G(ev_handlers_count); i++) {
1619+
if (ZEND_ASYNC_G(ev_handlers)[i] == handler) {
1620+
return false; /* Already registered */
1621+
}
1622+
}
1623+
1624+
/* Check if we have space */
1625+
if (ZEND_ASYNC_G(ev_handlers_count) >= 4) {
1626+
zend_throw_error(NULL, "Too many event handlers registered, maximum is 4");
1627+
return false;
1628+
}
1629+
1630+
/* Add handler */
1631+
ZEND_ASYNC_G(ev_handlers)[ZEND_ASYNC_G(ev_handlers_count)] = handler;
1632+
ZEND_ASYNC_G(ev_handlers_count)++;
1633+
1634+
return true;
1635+
}
1636+
1637+
ZEND_API bool zend_async_ev_handler_unregister(const zend_async_ev_handler_fn handler)
1638+
{
1639+
if (UNEXPECTED(handler == NULL)) {
1640+
return false;
1641+
}
1642+
1643+
for (int i = 0; i < ZEND_ASYNC_G(ev_handlers_count); i++) {
1644+
if (ZEND_ASYNC_G(ev_handlers)[i] == handler) {
1645+
/* Shift remaining handlers */
1646+
for (int j = i; j < ZEND_ASYNC_G(ev_handlers_count) - 1; j++) {
1647+
ZEND_ASYNC_G(ev_handlers)[j] = ZEND_ASYNC_G(ev_handlers)[j + 1];
1648+
}
1649+
ZEND_ASYNC_G(ev_handlers_count)--;
1650+
return true;
1651+
}
1652+
}
1653+
1654+
return false;
1655+
}

Zend/zend_async_API.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ typedef struct _zend_async_group_s zend_async_group_t;
139139
typedef struct _zend_fcall_s zend_fcall_t;
140140
typedef void (*zend_coroutine_entry_t)(void);
141141

142+
/* The event loop additional handler function type */
143+
typedef void (*zend_async_ev_handler_fn)(bool no_wait);
144+
142145
/* Channel method function types */
143146
typedef bool (*zend_channel_send_t)(zend_async_channel_t *channel, zval *value);
144147
typedef bool (*zend_channel_receive_t)(zend_async_channel_t *channel, zval *result);
@@ -1176,6 +1179,9 @@ typedef struct {
11761179
zend_coroutine_t *scheduler;
11771180
/* Exit exception object */
11781181
zend_object *exit_exception;
1182+
/* An array of additional handlers for the EventLoop that will be invoked by the reactor */
1183+
zend_async_ev_handler_fn ev_handlers[4]; /* Static array for event handlers */
1184+
int ev_handlers_count; /* Current number of handlers */
11791185
} zend_async_globals_t;
11801186

11811187
BEGIN_EXTERN_C()
@@ -1210,6 +1216,17 @@ END_EXTERN_C()
12101216
#define ZEND_ASYNC_MAIN_SCOPE ZEND_ASYNC_G(main_scope)
12111217
#define ZEND_ASYNC_SCHEDULER ZEND_ASYNC_G(scheduler)
12121218

1219+
#define ZEND_ASYNC_EV_HANDLER_REGISTER(handler) zend_async_ev_handler_register(handler)
1220+
#define ZEND_ASYNC_EV_HANDLER_UNREGISTER(handler) zend_async_ev_handler_unregister(handler)
1221+
1222+
/* Call all registered event loop handlers */
1223+
#define ZEND_ASYNC_EV_HANDLERS_CALL(no_wait) do { \
1224+
int _count = ZEND_ASYNC_G(ev_handlers_count); \
1225+
for (int _i = 0; _i < _count; _i++) { \
1226+
ZEND_ASYNC_G(ev_handlers)[_i](no_wait); \
1227+
} \
1228+
} while (0)
1229+
12131230
#define ZEND_ASYNC_INCREASE_EVENT_COUNT if (ZEND_ASYNC_G(active_event_count) < UINT_MAX) { \
12141231
ZEND_ASYNC_G(active_event_count)++; \
12151232
} else { \
@@ -1245,6 +1262,10 @@ void zend_async_api_shutdown(void);
12451262
void zend_async_globals_ctor(void);
12461263
void zend_async_globals_dtor(void);
12471264

1265+
/* LibUv event loop handlers API */
1266+
ZEND_API bool zend_async_ev_handler_register(zend_async_ev_handler_fn handler);
1267+
ZEND_API bool zend_async_ev_handler_unregister(zend_async_ev_handler_fn handler);
1268+
12481269
ZEND_API const char * zend_async_get_api_version(void);
12491270
ZEND_API int zend_async_get_api_version_number(void);
12501271

0 commit comments

Comments
 (0)