19 #include <sys/types.h>
35 #include <sys/event.h>
38 #include <sys/epoll.h>
39 #include <sys/timerfd.h>
56 #define ULOOP_MAX_EVENTS 10
86 if (signo >= 1 && signo <= 64)
87 *signums |= (1u << (signo - 1));
92 return (signo >= 1) && (signo <= 64) && (signums & (1u << (signo - 1)));
103 nsigs = read(
fd->fd, buf,
sizeof(buf));
105 for (ssize_t i = 0; i < nsigs; i++)
123 fcntl(
fd, F_SETFD, fcntl(
fd, F_GETFD) | FD_CLOEXEC);
124 fcntl(
fd, F_SETFL, fcntl(
fd, F_GETFL) | O_NONBLOCK);
244 fl = fcntl(sock->
fd, F_GETFL, 0);
246 fcntl(sock->
fd, F_SETFL, fl);
283 fd->registered =
false;
291 static int64_t
tv_diff(
struct timeval *t1,
struct timeval *t2)
294 (t1->tv_sec - t2->tv_sec) * 1000 +
295 (t1->tv_usec - t2->tv_usec) / 1000;
323 clock_gettime(CLOCK_MONOTONIC, &ts);
324 tv->tv_sec = ts.tv_sec;
325 tv->tv_usec = ts.tv_nsec / 1000;
330 struct timeval *time = &timeout->
time;
337 time->tv_sec += msecs / 1000;
338 time->tv_usec += (msecs % 1000) * 1000;
340 if (time->tv_usec > 1000000) {
342 time->tv_usec -= 1000000;
373 else if (td < INT_MIN)
432 pid = waitpid(-1, &ret, WNOHANG);
433 if (
pid < 0 && errno == EINTR)
470 uint8_t sigbyte = signo;
472 if (signo == SIGCHLD)
494 struct sigaction *act;
497 sigaction(signum, NULL, &s);
500 if (s.sa_handler == SIG_DFL) {
501 memcpy(old, &s,
sizeof(
struct sigaction));
502 s.sa_handler = handler;
507 else if (s.sa_handler == handler) {
512 sigaction(signum, act, NULL);
518 void *new_handler = NULL;
520 sigaction(signum, NULL, &s);
523 if (s.sa_handler == SIG_DFL)
524 new_handler = SIG_IGN;
526 if (s.sa_handler == SIG_IGN)
527 new_handler = SIG_DFL;
531 s.sa_handler = new_handler;
533 sigaction(signum, &s, NULL);
539 static struct sigaction old_sigint, old_sigchld, old_sigterm;
574 sigemptyset(&sa.sa_mask);
575 sigaction(s->
signo, &sa, NULL);
676 if (timeout >= 0 && (next_time < 0 || timeout < next_time))
#define LIST_HEAD_INIT(name)
static void list_add_tail(struct list_head *_new, struct list_head *head)
#define list_for_each_entry_safe(p, n, h, field)
#define list_for_each_entry(p, h, field)
static bool list_empty(const struct list_head *head)
static void list_del(struct list_head *entry)
#define list_first_entry(ptr, type, field)
struct uloop_fd_stack * next
static struct epoll_event events[ULOOP_MAX_EVENTS]
static int register_poll(struct uloop_fd *fd, unsigned int flags)
static int uloop_fetch_events(int timeout)
static int uloop_init_pollfd(void)
static int timer_register(struct uloop_interval *tm, unsigned int msecs)
static int timer_remove(struct uloop_interval *tm)
static int __uloop_fd_delete(struct uloop_fd *sock)
static int64_t timer_next(struct uloop_interval *tm)
static struct list_head signals
static void uloop_clear_processes(void)
int64_t uloop_timeout_remaining64(struct uloop_timeout *timeout)
int uloop_run_timeout(int timeout)
static void uloop_signal_wake(int signo)
int uloop_get_next_timeout(void)
int uloop_signal_add(struct uloop_signal *s)
static void uloop_run_events(int64_t timeout)
static void uloop_setup_signals(bool add)
static struct list_head timeouts
int uloop_interval_set(struct uloop_interval *timer, unsigned int msecs)
static int uloop_run_depth
int uloop_process_delete(struct uloop_process *p)
int uloop_fd_add(struct uloop_fd *sock, unsigned int flags)
static void uloop_install_handler(int signum, void(*handler)(int), struct sigaction *old, bool add)
static void uloop_handle_processes(void)
int uloop_timeout_cancel(struct uloop_timeout *timeout)
int uloop_fd_delete(struct uloop_fd *fd)
static int64_t tv_diff(struct timeval *t1, struct timeval *t2)
static struct uloop_fd_event cur_fds[10]
static void set_signo(uint64_t *signums, int signo)
static struct uloop_fd waker_fd
bool uloop_handle_sigchld
static void uloop_gettime(struct timeval *tv)
static void signal_consume(struct uloop_fd *fd, unsigned int events)
static void uloop_handle_sigint(int signo)
static void waker_init_fd(int fd)
static void uloop_process_timeouts(void)
uloop_fd_handler uloop_fd_set_cb
int uloop_signal_delete(struct uloop_signal *s)
int64_t uloop_interval_remaining(struct uloop_interval *timer)
static bool uloop_fd_stack_event(struct uloop_fd *fd, int events)
static struct list_head processes
int uloop_timeout_remaining(struct uloop_timeout *timeout)
static void uloop_ignore_signal(int signum, bool ignore)
int uloop_interval_cancel(struct uloop_interval *timer)
bool uloop_cancelling(void)
int uloop_timeout_add(struct uloop_timeout *timeout)
static int waker_init(void)
int uloop_timeout_set(struct uloop_timeout *timeout, int msecs)
static bool get_signo(uint64_t signums, int signo)
int uloop_process_add(struct uloop_process *p)
static struct uloop_fd_stack * fd_stack
static void uloop_clear_timeouts(void)
#define ULOOP_EVENT_BUFFERED
void(* uloop_fd_handler)(struct uloop_fd *u, unsigned int events)
#define ULOOP_EDGE_TRIGGER