You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
4.6 KiB
111 lines
4.6 KiB
// uasync.h |
|
|
|
// модуль асинхронных операций. добавляем сокеты и таймауты и mainloop их обслуживает. |
|
|
|
#ifndef UASYNC_H |
|
#define UASYNC_H |
|
|
|
#include "platform_compat.h" |
|
#include <stddef.h> |
|
#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); |
|
|
|
struct posted_task { |
|
uasync_post_callback_t callback; |
|
void* arg; |
|
struct posted_task* next; |
|
}; |
|
|
|
// Uasync instance structure |
|
struct UASYNC { |
|
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); |
|
|
|
// 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); |
|
|
|
#endif // UASYNC_H
|
|
|