Skip to content

Commit 558a213

Browse files
committed
php#53: Refactor network_async_await_stream_socket to use unified event handling
This commit addresses architectural inconsistencies in async socket event management by unifying the approach used across the codebase. Changes: - Modified network_async_await_stream_socket() to accept php_stream* instead of php_netstream_data_t*, enabling access to the standard Stream API - Replaced direct ZEND_ASYNC_NEW_SOCKET_EVENT() calls with unified php_stream_set_option(PHP_STREAM_OPTION_ASYNC_EVENT_HANDLE) approach - Updated all call sites in xp_socket.c to pass stream instead of sock data - Ensured consistent event handle creation/retrieval across all async operations
1 parent 121e960 commit 558a213

File tree

3 files changed

+25
-22
lines changed

3 files changed

+25
-22
lines changed

main/network_async.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,18 +204,17 @@ static void socket_await_callback_resolve(
204204
}
205205

206206
/**
207-
* Asynchronous await for single socket with reusable event handle.
207+
* Asynchronous await for single socket stream with reusable event handle.
208208
*
209-
* This function provides optimized async I/O waiting for a single socket by reusing
210-
* the event handle stored in the socket structure, avoiding repeated
211-
* ZEND_ASYNC_NEW_SOCKET_EVENT allocations.
209+
* This function provides optimized async I/O waiting for a single socket stream by using
210+
* the unified php_stream_set_option approach for event handle management.
212211
*
213-
* @param sock Socket data structure containing event handle
212+
* @param stream PHP stream (must be a socket stream)
214213
* @param events Poll events (POLLIN, POLLOUT, etc.)
215214
* @param timeout Timeout as struct timeval* (NULL for infinite)
216215
* @return 1 if events occurred, 0 on timeout, -1 on error
217216
*/
218-
ZEND_API int network_async_await_stream_socket(php_netstream_data_t *sock, short events, struct timeval *timeout)
217+
ZEND_API int network_async_await_stream_socket(php_stream *stream, short events, struct timeval *timeout)
219218
{
220219
zend_coroutine_t *coroutine = ZEND_ASYNC_CURRENT_COROUTINE;
221220

@@ -224,21 +223,25 @@ ZEND_API int network_async_await_stream_socket(php_netstream_data_t *sock, short
224223
return -1;
225224
}
226225

227-
if (sock == NULL || sock->socket == -1) {
226+
if (stream == NULL) {
228227
errno = EBADF;
229228
return -1;
230229
}
231230

232-
// Create or reuse event handle
233-
if (sock->poll_event == NULL) {
234-
sock->poll_event = ZEND_ASYNC_NEW_SOCKET_EVENT(
235-
sock->socket, poll2_events_to_async(events)
236-
);
237-
238-
if (UNEXPECTED(EG(exception) != NULL || sock->poll_event == NULL)) {
239-
errno = ENOMEM;
240-
return -1;
241-
}
231+
// Use unified approach: get event handle via php_stream_set_option
232+
zend_async_poll_event_t *poll_event = NULL;
233+
zend_ulong async_events = poll2_events_to_async(events);
234+
235+
php_stream_set_option(stream, PHP_STREAM_OPTION_ASYNC_EVENT_HANDLE, async_events, &poll_event);
236+
237+
if (UNEXPECTED(EG(exception) != NULL)) {
238+
handle_exception_and_errno();
239+
return -1;
240+
}
241+
242+
if (UNEXPECTED(poll_event == NULL)) {
243+
errno = ENOTSUP; // Stream doesn't support async operations
244+
return -1;
242245
}
243246

244247
// Convert timeval timeout to milliseconds for async waker
@@ -257,7 +260,7 @@ ZEND_API int network_async_await_stream_socket(php_netstream_data_t *sock, short
257260
// Register the event
258261
zend_async_resume_when(
259262
coroutine,
260-
&sock->poll_event->base,
263+
&poll_event->base,
261264
false,
262265
socket_await_callback_resolve,
263266
NULL

main/network_async.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ BEGIN_EXTERN_C()
2323
ZEND_API void network_async_set_socket_blocking(php_socket_t socket, bool blocking, php_netstream_data_t *sock_data);
2424
ZEND_API bool network_async_ensure_socket_nonblocking(php_socket_t socket);
2525
ZEND_API void network_async_wait_socket(php_socket_t socket, const zend_ulong events, const zend_ulong timeout);
26-
ZEND_API int network_async_await_stream_socket(php_netstream_data_t *sock, short events, struct timeval *timeout);
26+
ZEND_API int network_async_await_stream_socket(php_stream *stream, short events, struct timeval *timeout);
2727

2828
ZEND_API int php_poll2_async(php_pollfd *ufds, unsigned int nfds, int timeout);
2929
ZEND_API int php_select_async(php_socket_t max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv);

main/streams/xp_socket.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static ssize_t php_sockop_write(php_stream *stream, const char *buf, size_t coun
9292
sock->timeout_event = false;
9393

9494
if (ZEND_ASYNC_IS_ACTIVE) {
95-
retval = network_async_await_stream_socket(sock, POLLOUT, ptimeout);
95+
retval = network_async_await_stream_socket(stream, POLLOUT, ptimeout);
9696

9797
if (retval == 0) {
9898
sock->timeout_event = true;
@@ -172,7 +172,7 @@ static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data
172172
}
173173

174174
if (ZEND_ASYNC_IS_ACTIVE) {
175-
retval = network_async_await_stream_socket(sock, PHP_POLLREADABLE, ptimeout);
175+
retval = network_async_await_stream_socket(stream, PHP_POLLREADABLE, ptimeout);
176176

177177
if (retval == 0) {
178178
sock->timeout_event = true;
@@ -410,7 +410,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void
410410
((MSG_DONTWAIT != 0) || !sock->is_blocked)
411411
) ||
412412
(ZEND_ASYNC_IS_ACTIVE ?
413-
network_async_await_stream_socket(sock, PHP_POLLREADABLE|POLLPRI, &tv) > 0 :
413+
network_async_await_stream_socket(stream, PHP_POLLREADABLE|POLLPRI, &tv) > 0 :
414414
php_pollfd_for(sock->socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0)
415415
) {
416416
/* the poll() call was skipped if the socket is non-blocking (or MSG_DONTWAIT is available) and if the timeout is zero */

0 commit comments

Comments
 (0)