Fix u_async: Windows socket registration, timers, and poll issues

- Remove FD_SETSIZE check for Windows sockets (can have any value)
- Fix process_timeouts to handle all expired timers (continue instead of break)
- Handle case when no sockets to poll (sleep instead of calling poll)
- Disable wakeup pipe on Windows (incompatible with WSAPoll)
- Add gettimeofday and ssize_t implementations for Windows
This commit is contained in:
jeka committed 2026-02-15 17:38:45 +03:00
1 parent 53c7330a7f
commit c8af35c4b9
2 files changed
+58 -7

No files matched your search

+30 -5
View File
@@ -112,7 +112,11 @@ static int socket_array_add_internal(struct socket_array* sa, int fd, socket_t s
socket_callback_t read_cbk_fd, socket_callback_t write_cbk_fd,
socket_t_callback_t read_cbk_sock, socket_t_callback_t write_cbk_sock,
socket_callback_t except_cbk, void* user_data) {
if (!sa || fd < 0 || fd >= FD_SETSIZE) return -1;
if (!sa || fd < 0) return -1;
// FD_SETSIZE check only for POSIX systems - Windows sockets can have any value
#ifndef _WIN32
if (fd >= FD_SETSIZE) return -1;
#endif
if (fd >= sa->capacity) {
// Need to resize - double the capacity
int new_capacity = sa->capacity * 2;
@@ -197,10 +201,11 @@ static int socket_array_add_socket_t(struct socket_array* sa, socket_t sock, soc
// On Windows, SOCKET is UINT_PTR, so we need to handle indexing differently
#ifdef _WIN32
int fd = (int)(intptr_t)sock; // Use socket value as index on Windows (simplified)
if (fd < 0) return -1; // Windows sockets can have any value, only check negative
#else
int fd = sock; // On POSIX, socket_t is int
#endif
if (fd < 0 || fd >= FD_SETSIZE) return -1;
#endif
return socket_array_add_internal(sa, fd, sock, SOCKET_NODE_TYPE_SOCK,
NULL, NULL, read_cbk, write_cbk, except_cbk, user_data);
}
@@ -330,7 +335,7 @@ static void process_timeouts(struct UASYNC* ua) {
node->ua->timer_free_count++;
}
free(node);
break;
continue; // Process next expired timeout
}
}
@@ -765,7 +770,20 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
// Include wakeup pipe if initialized
int wakeup_fd_present = ua->wakeup_initialized && ua->wakeup_pipe[0] >= 0;
int total_fds = socket_count + wakeup_fd_present;
// If no sockets to poll, just wait and process timeouts
if (total_fds == 0) {
if (timeout_ms > 0) {
#ifdef _WIN32
Sleep(timeout_ms);
#else
usleep(timeout_ms * 1000);
#endif
}
process_timeouts(ua);
return;
}
// Rebuild poll_fds if dirty or not allocated
if (ua->poll_fds_dirty || !ua->poll_fds) {
rebuild_poll_fds(ua);
@@ -881,7 +899,8 @@ struct UASYNC* uasync_create(void) {
ua->wakeup_pipe[1] = -1;
ua->wakeup_initialized = 0;
// Create wakeup pipe
// Create wakeup pipe (skip on Windows - pipes don't work with poll/WSAPoll)
#ifndef _WIN32
if (pipe(ua->wakeup_pipe) < 0) {
DEBUG_WARN(DEBUG_CATEGORY_UASYNC, "Failed to create wakeup pipe: %s", strerror(errno));
// Continue without wakeup mechanism
@@ -895,6 +914,12 @@ struct UASYNC* uasync_create(void) {
fcntl(ua->wakeup_pipe[0], F_SETFL, flags | O_NONBLOCK);
}
}
#else
// On Windows, pipes don't work with WSAPoll - skip wakeup mechanism
ua->wakeup_pipe[0] = -1;
ua->wakeup_pipe[1] = -1;
ua->wakeup_initialized = 0;
#endif
ua->sockets = socket_array_create(16);
if (!ua->sockets) {