#define _POSIX_C_SOURCE 200809L #include "yasl/yasl.h" #include #include #include #include #include #define YASL_MAX_FDS 64 typedef int (*yasl_loop_fd_fn)(int fd, short revents, void *ud); struct yasl_fd_source { yasl_loop_fd_fn fn; void *ud; int id; int fd; short events; }; struct yasl_loop { struct yasl_fd_source fds[YASL_MAX_FDS]; struct pollfd pollfds[YASL_MAX_FDS]; int count; int next_id; bool running; }; uint64_t yasl_loop_now_ns(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec; } struct yasl_loop *yasl_loop_create(void) { struct yasl_loop *l = calloc(1, sizeof(*l)); if (!l) return NULL; l->next_id = 1; return l; } void yasl_loop_destroy(struct yasl_loop *l) { free(l); } int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events, int (*fn)(int fd, short revents, void *ud), void *ud) { if (!l || l->count >= YASL_MAX_FDS || fd < 0) return -1; int id = l->next_id++; l->fds[l->count] = (struct yasl_fd_source){ .fn = fn, .ud = ud, .id = id, .fd = fd, .events = events, }; l->pollfds[l->count] = (struct pollfd){ .fd = fd, .events = events, .revents = 0, }; l->count++; return id; } int yasl_loop_del_fd(struct yasl_loop *l, int id) { if (!l || id <= 0) return -1; for (int i = 0; i < l->count; i++) { if (l->fds[i].id == id) { l->count--; l->fds[i] = l->fds[l->count]; l->pollfds[i] = l->pollfds[l->count]; return 0; } } return -1; } int yasl_loop_set_fd_events(struct yasl_loop *l, int id, short events) { if (!l || id <= 0) return -1; for (int i = 0; i < l->count; i++) { if (l->fds[i].id == id) { l->fds[i].events = events; l->pollfds[i].events = events; return 0; } } return -1; } void yasl_loop_kick(struct yasl_loop *l) { (void)l; } int yasl_loop_run(struct yasl_loop *l) { if (!l) return -1; l->running = true; while (l->running) { int n = poll(l->pollfds, (nfds_t)l->count, -1); if (n < 0) { if (errno == EINTR) continue; return -1; } for (int i = 0; i < l->count && l->running; i++) { if (l->pollfds[i].revents) { struct yasl_fd_source src = l->fds[i]; short revents = l->pollfds[i].revents; l->pollfds[i].revents = 0; if (src.fn) src.fn(src.fd, revents, src.ud); } } } return 0; } void yasl_loop_quit(struct yasl_loop *l) { if (l) l->running = false; }