// uasync.h // модуль асинхронных операций. добавляем сокеты и таймауты и mainloop их обслуживает. #ifndef UASYNC_H #define UASYNC_H #include "platform_compat.h" #include #include "timeout_heap.h" #include "socket_compat.h" typedef void (*timeout_callback_t)(void* user_arg);// передаёт user_arg из uasync_set_timeout typedef void (*socket_callback_t)(int fd, void* user_arg);// передаёт user_arg из uasync_add_socket (for pipe/file) typedef void (*socket_t_callback_t)(socket_t sock, void* user_arg);// передаёт user_arg из uasync_add_socket_t (for sockets) // user_arg полезен если нужно передать управляющую структуру. Ее можно выделить в памяти и в ней хранить всё что надо. т.е. при set_timeout передаём и получаем ее в callback-е // Error type typedef int err_t; #define ERR_OK 0 #define ERR_FAIL -1 // Socket node types #define SOCKET_NODE_TYPE_FD 0 // Regular file descriptor (pipe, file) #define SOCKET_NODE_TYPE_SOCK 1 // Socket (socket_t) typedef void (*uasync_post_callback_t)(void* user_arg); #include "memory_pool.h" struct timeout_node; // Forward declaration struct posted_task { uasync_post_callback_t callback; void* arg; struct posted_task* next; }; // Uasync instance structure struct UASYNC { struct memory_pool* timeout_pool; // Pool for timeout_node allocation struct timeout_node* immediate_queue_head; // FIFO queue for immediate execution struct timeout_node* immediate_queue_tail; TimeoutHeap* timeout_heap; // Heap for timeout management struct socket_array* sockets; // Array-based socket management // Debug counters for memory allocation tracking size_t timer_alloc_count; size_t timer_free_count; size_t socket_alloc_count; size_t socket_free_count; // Wakeup pipe for interrupting poll int wakeup_pipe[2]; // [0] read, [1] write int wakeup_initialized; // Cached pollfd array for optimized poll operations (fallback for non-Linux) struct pollfd* poll_fds; // Pre-allocated pollfd array int poll_fds_capacity; // Current capacity of poll_fds int poll_fds_count; // Number of valid entries in poll_fds int poll_fds_dirty; // 1 if poll_fds needs rebuild // Epoll support (Linux only) int epoll_fd; // epoll file descriptor (-1 if not using epoll) int use_epoll; // 1 if using epoll, 0 if using poll struct posted_task* posted_tasks_head; struct posted_task* posted_tasks_tail; #ifdef _WIN32 CRITICAL_SECTION posted_lock; #else pthread_mutex_t posted_lock; #endif }; // Type definitions typedef struct UASYNC uasync_t; typedef struct UASYNC UASYNC_t; // Instance API - основной API для работы с uasync struct UASYNC* uasync_create(void); void uasync_destroy(struct UASYNC* ua, int close_fds); void uasync_init_instance(struct UASYNC* ua); // текущее время (timebase 0.1ms) uint64_t get_time_tb(void); // Timeouts, timebase = 0.1 mS void* uasync_set_timeout(struct UASYNC* ua, int timeout_tb, void* user_arg, timeout_callback_t callback); err_t uasync_cancel_timeout(struct UASYNC* ua, void* t_id); // Immediate execution in next mainloop (FIFO order) void* uasync_call_soon(struct UASYNC* ua, void* user_arg, timeout_callback_t callback); err_t uasync_call_soon_cancel(struct UASYNC* ua, void* t_id); // Sockets - for regular file descriptors (pipe, file) void* uasync_add_socket(struct UASYNC* ua, int fd, socket_callback_t read_cbk, socket_callback_t write_cbk, socket_callback_t except_cbk, void* user_arg); // Sockets - for socket_t (cross-platform sockets) void* uasync_add_socket_t(struct UASYNC* ua, socket_t sock, socket_t_callback_t read_cbk, socket_t_callback_t write_cbk, socket_t_callback_t except_cbk, void* user_arg); err_t uasync_remove_socket(struct UASYNC* ua, void* s_id); err_t uasync_remove_socket_t(struct UASYNC* ua, socket_t sock); // Single iteration of event loop with timeout (timebase units) void uasync_poll(struct UASYNC* ua, int timeout_tb); // Mainloop (бесконечный цикл, __noreturn) void uasync_mainloop(struct UASYNC* ua); // Debug statistics void uasync_get_stats(struct UASYNC* ua, size_t* timer_alloc, size_t* timer_free, size_t* socket_alloc, size_t* socket_free); // Lookup socket by file descriptor - returns current pointer even after realloc int uasync_lookup_socket(struct UASYNC* ua, int fd, void** socket_id); // Print all resources (timers, sockets) for debugging void uasync_print_resources(struct UASYNC* ua, const char* prefix); // Wakeup mechanism for interrupting poll int uasync_wakeup(struct UASYNC* ua); int uasync_get_wakeup_fd(struct UASYNC* ua); // returns write fd for wakeup pipe (for signal handlers) // сообщить async (из другого thread) чтобы он вызвал callback с аргументом void uasync_post(struct UASYNC* ua, uasync_post_callback_t callback, void* user_arg); // синхронизация памяти (для доступности из других потоков) void uasync_memsync(struct UASYNC* ua); #endif // UASYNC_H