Browse Source

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
nodeinfo-routing-update
jeka 2 months ago
parent
commit
c8af35c4b9
  1. 30
      lib/platform_compat.h
  2. 35
      lib/u_async.c

30
lib/platform_compat.h

@ -39,8 +39,34 @@
#define POLLPRI 0x0002
#endif
// gettimeofday for Windows (use system implementation if available)
#include <sys/time.h>
// ssize_t for Windows (signed size type)
#ifndef _SSIZE_T_DEFINED
typedef long ssize_t;
#define _SSIZE_T_DEFINED
#endif
// gettimeofday for Windows - provide our own implementation
static inline int gettimeofday(struct timeval *tv, void *tz) {
FILETIME ft;
unsigned __int64 tmpres = 0;
if (tv != NULL) {
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
// Convert from 100-nanosecond intervals to microseconds
tmpres /= 10;
// Convert to Unix epoch (January 1, 1970)
tmpres -= 11644473600000000ULL;
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
// tz parameter is ignored (for compatibility with POSIX)
return 0;
}
// Pipe creation for Windows
static inline int platform_pipe(int pipefd[2]) {

35
lib/u_async.c

@ -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) {

Loading…
Cancel
Save