#ifndef FUSED_EVENTS_H #define FUSED_EVENTS_H #include #include #include #include "ws_client.h" #include "queue.h" #include "executor.h" #define MAX_EPOLL_FDS 64 /* Identifies the type of a tracked file descriptor */ typedef enum { FD_TYPE_WS, /* WebSocket connection */ FD_TYPE_TIMER, /* timerfd */ FD_TYPE_EVENT, /* eventfd for queue wakeup */ } fd_type_t; /* A file descriptor tracked by the epoll event loop */ typedef struct { int fd; /* the file descriptor */ fd_type_t type; /* type identifier for dispatch */ uint32_t ws_conn_idx; /* WebSocket connection index (if type is FD_TYPE_WS) */ void *user_data; /* optional user data pointer */ } tracked_fd_t; /* Epoll-based event set for a group of file descriptors */ typedef struct { int epoll_fd; /* epoll instance fd */ struct epoll_event events[MAX_EPOLL_FDS]; /* re-usable event array */ tracked_fd_t fds[MAX_EPOLL_FDS]; /* tracked fd descriptors */ uint32_t fd_count; /* number of tracked fds */ } epoll_set_t; /* Top-level event loop state, split into hot (ws) and cold (timer/http) paths */ typedef struct { epoll_set_t hot_epoll; /* hot epoll set for latency-sensitive ws events */ epoll_set_t cold_epoll; /* cold epoll set for timer/http events */ ws_client_t *ws_client; /* WebSocket client instance */ spsc_queue_t *signal_queue; /* signal queue for emitting opportunities */ executor_shared_t *executor_shared; /* shared executor state (in_flight + queue lock) */ int timer_fd; /* timerfd for periodic tasks */ int wakeup_fd; /* eventfd for waking the cold loop */ uint64_t next_ping_ms; /* next scheduled WebSocket ping timestamp */ bool running; /* false signals event loops to exit */ } event_loops_t; /* Initialise both epoll sets, create sockets, and start event loops */ int event_loops_init(event_loops_t *loops, ws_client_t *ws_client, spsc_queue_t *signal_queue, const config_t *cfg, int wakeup_fd); /* Tear down event loops, close all sockets */ void event_loops_destroy(event_loops_t *loops); /* Register a file descriptor with an epoll set */ int event_loops_add_fd(epoll_set_t *set, int fd, fd_type_t type, uint32_t ws_idx, void *user_data, uint32_t events); /* Remove a file descriptor from an epoll set */ void event_loops_remove_fd(epoll_set_t *set, int fd); /* Hot event loop thread: handles WebSocket I/O */ void *event_hot_thread(void *arg); /* Cold event loop thread (legacy, single-threaded) */ void *event_cold_thread(void *arg); /* Per-executor-thread entry point: creates its own executor_thread_t and polls signal queue */ void *event_executor_thread(void *arg); #endif