22
22
23
23
typedef struct {
24
24
php_poll_fd_table * fd_table ;
25
- /* Temporary arrays allocated during poll_backend_wait() */
26
25
struct pollfd * temp_fds ;
27
26
int temp_fds_capacity ;
28
27
} poll_backend_data_t ;
@@ -60,6 +59,9 @@ static uint32_t poll_events_from_native(uint32_t native)
60
59
if (native & POLLHUP ) {
61
60
events |= PHP_POLL_HUP ;
62
61
}
62
+ if (native & POLLNVAL ) {
63
+ events |= PHP_POLL_ERROR ; /* Map invalid FD to error */
64
+ }
63
65
return events ;
64
66
}
65
67
@@ -80,7 +82,6 @@ static zend_result poll_backend_init(php_poll_ctx *ctx)
80
82
return FAILURE ;
81
83
}
82
84
83
- /* Pre-allocate temporary pollfd array */
84
85
data -> temp_fds = php_poll_calloc (initial_capacity , sizeof (struct pollfd ), ctx -> persistent );
85
86
if (!data -> temp_fds ) {
86
87
php_poll_fd_table_cleanup (data -> fd_table );
@@ -148,7 +149,6 @@ static zend_result poll_backend_modify(php_poll_ctx *ctx, int fd, uint32_t event
148
149
149
150
entry -> events = events ;
150
151
entry -> data = user_data ;
151
- entry -> last_revents = 0 ;
152
152
153
153
return SUCCESS ;
154
154
}
@@ -186,40 +186,6 @@ static bool poll_build_fds_callback(int fd, php_poll_fd_entry *entry, void *user
186
186
return true;
187
187
}
188
188
189
- /* Context for processing poll results */
190
- typedef struct {
191
- poll_backend_data_t * backend_data ;
192
- struct pollfd * pollfds ;
193
- php_poll_event * events ;
194
- int max_events ;
195
- int event_count ;
196
- } poll_result_context ;
197
-
198
- /* Callback to process poll results */
199
- static bool poll_process_results_callback (int fd , php_poll_fd_entry * entry , void * user_data )
200
- {
201
- poll_result_context * ctx = (poll_result_context * ) user_data ;
202
-
203
- if (ctx -> event_count >= ctx -> max_events ) {
204
- return false; /* Stop if events array is full */
205
- }
206
-
207
- /* Find the corresponding pollfd entry */
208
- for (int i = 0 ; i < php_poll_fd_table_count (ctx -> backend_data -> fd_table ); i ++ ) {
209
- if (ctx -> pollfds [i ].fd == fd && ctx -> pollfds [i ].revents != 0 ) {
210
- ctx -> events [ctx -> event_count ].fd = fd ;
211
- ctx -> events [ctx -> event_count ].events = entry -> events ;
212
- ctx -> events [ctx -> event_count ].revents
213
- = poll_events_from_native (ctx -> pollfds [i ].revents );
214
- ctx -> events [ctx -> event_count ].data = entry -> data ;
215
- ctx -> event_count ++ ;
216
- break ;
217
- }
218
- }
219
-
220
- return true;
221
- }
222
-
223
189
static int poll_backend_wait (php_poll_ctx * ctx , php_poll_event * events , int max_events , int timeout )
224
190
{
225
191
poll_backend_data_t * backend_data = (poll_backend_data_t * ) ctx -> backend_data ;
@@ -254,28 +220,42 @@ static int poll_backend_wait(php_poll_ctx *ctx, php_poll_event *events, int max_
254
220
/* Call poll() */
255
221
int nfds = poll (backend_data -> temp_fds , fd_count , timeout );
256
222
257
- if (nfds > 0 ) {
258
- /* Process results */
259
- poll_result_context result_ctx = { .backend_data = backend_data ,
260
- .pollfds = backend_data -> temp_fds ,
261
- .events = events ,
262
- .max_events = max_events ,
263
- .event_count = 0 };
264
-
265
- php_poll_fd_table_foreach (
266
- backend_data -> fd_table , poll_process_results_callback , & result_ctx );
267
- int event_count = result_ctx .event_count ;
268
-
269
- /* Handle oneshot removals */
270
- for (int i = 0 ; i < nfds ; i ++ ) {
271
- php_poll_fd_entry * entry = php_poll_fd_table_find (backend_data -> fd_table , events [i ].fd );
272
- if (entry && (entry -> events & PHP_POLL_ONESHOT ) && events [i ].revents != 0 ) {
273
- php_poll_fd_table_remove (backend_data -> fd_table , events [i ].fd );
223
+ if (nfds <= 0 ) {
224
+ return nfds ; /* Return 0 for timeout, -1 for error */
225
+ }
226
+
227
+ /* Process results - iterate through pollfd array directly */
228
+ int event_count = 0 ;
229
+ for (int i = 0 ; i < fd_count && event_count < max_events ; i ++ ) {
230
+ struct pollfd * pfd = & backend_data -> temp_fds [i ];
231
+
232
+ if (pfd -> revents != 0 ) {
233
+ php_poll_fd_entry * entry = php_poll_fd_table_find (backend_data -> fd_table , pfd -> fd );
234
+ if (entry ) {
235
+ /* Handle POLLNVAL by automatically removing the invalid FD */
236
+ if (pfd -> revents & POLLNVAL ) {
237
+ php_poll_fd_table_remove (backend_data -> fd_table , pfd -> fd );
238
+ continue ; /* Don't report this event */
239
+ }
240
+
241
+ events [event_count ].fd = pfd -> fd ;
242
+ events [event_count ].events = entry -> events ;
243
+ events [event_count ].revents = poll_events_from_native (pfd -> revents );
244
+ events [event_count ].data = entry -> data ;
245
+ event_count ++ ;
274
246
}
275
247
}
276
248
}
277
249
278
- return nfds ;
250
+ /* Handle oneshot removals */
251
+ for (int i = 0 ; i < event_count ; i ++ ) {
252
+ php_poll_fd_entry * entry = php_poll_fd_table_find (backend_data -> fd_table , events [i ].fd );
253
+ if (entry && (entry -> events & PHP_POLL_ONESHOT ) && events [i ].revents != 0 ) {
254
+ php_poll_fd_table_remove (backend_data -> fd_table , events [i ].fd );
255
+ }
256
+ }
257
+
258
+ return event_count ;
279
259
}
280
260
281
261
static bool poll_backend_is_available (void )
0 commit comments