ustream: prevent recursive calls to the read callback
[project/libubox.git] / uloop.h
1 /*
2 * uloop - event loop implementation
3 *
4 * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 #ifndef _ULOOP_H__
19 #define _ULOOP_H__
20
21 #include <sys/time.h>
22 #include <sys/types.h>
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <signal.h>
26
27 #if defined(__APPLE__) || defined(__FreeBSD__)
28 #define USE_KQUEUE
29 #else
30 #define USE_EPOLL
31 #endif
32
33 #include "list.h"
34
35 struct uloop_fd;
36 struct uloop_timeout;
37 struct uloop_process;
38 struct uloop_interval;
39 struct uloop_signal;
40
41 typedef void (*uloop_fd_handler)(struct uloop_fd *u, unsigned int events);
42 typedef void (*uloop_timeout_handler)(struct uloop_timeout *t);
43 typedef void (*uloop_process_handler)(struct uloop_process *c, int ret);
44 typedef void (*uloop_interval_handler)(struct uloop_interval *t);
45 typedef void (*uloop_signal_handler)(struct uloop_signal *s);
46
47 #define ULOOP_READ (1 << 0)
48 #define ULOOP_WRITE (1 << 1)
49 #define ULOOP_EDGE_TRIGGER (1 << 2)
50 #define ULOOP_BLOCKING (1 << 3)
51
52 #define ULOOP_EVENT_MASK (ULOOP_READ | ULOOP_WRITE)
53
54 /* internal flags */
55 #define ULOOP_EVENT_BUFFERED (1 << 4)
56 #ifdef USE_KQUEUE
57 #define ULOOP_EDGE_DEFER (1 << 5)
58 #endif
59
60 #define ULOOP_ERROR_CB (1 << 6)
61
62 struct uloop_fd
63 {
64 uloop_fd_handler cb;
65 int fd;
66 bool eof;
67 bool error;
68 bool registered;
69 uint8_t flags;
70 };
71
72 struct uloop_timeout
73 {
74 struct list_head list;
75 bool pending;
76
77 uloop_timeout_handler cb;
78 struct timeval time;
79 };
80
81 struct uloop_process
82 {
83 struct list_head list;
84 bool pending;
85
86 uloop_process_handler cb;
87 pid_t pid;
88 };
89
90 struct uloop_interval
91 {
92 uloop_interval_handler cb;
93 uint64_t expirations;
94
95 union {
96 struct uloop_fd ufd;
97 struct {
98 int64_t fired;
99 unsigned int msecs;
100 } time;
101 } priv;
102 };
103
104 struct uloop_signal
105 {
106 struct list_head list;
107 struct sigaction orig;
108 bool pending;
109
110 uloop_signal_handler cb;
111 int signo;
112 };
113
114 extern bool uloop_cancelled;
115 extern bool uloop_handle_sigchld;
116 extern uloop_fd_handler uloop_fd_set_cb;
117
118 int uloop_fd_add(struct uloop_fd *sock, unsigned int flags);
119 int uloop_fd_delete(struct uloop_fd *sock);
120
121 int uloop_get_next_timeout(void);
122 int uloop_timeout_add(struct uloop_timeout *timeout);
123 int uloop_timeout_set(struct uloop_timeout *timeout, int msecs);
124 int uloop_timeout_cancel(struct uloop_timeout *timeout);
125 int uloop_timeout_remaining(struct uloop_timeout *timeout) __attribute__((deprecated("use uloop_timeout_remaining64")));
126 int64_t uloop_timeout_remaining64(struct uloop_timeout *timeout);
127
128 int uloop_process_add(struct uloop_process *p);
129 int uloop_process_delete(struct uloop_process *p);
130
131 int uloop_interval_set(struct uloop_interval *timer, unsigned int msecs);
132 int uloop_interval_cancel(struct uloop_interval *timer);
133 int64_t uloop_interval_remaining(struct uloop_interval *timer);
134
135 int uloop_signal_add(struct uloop_signal *s);
136 int uloop_signal_delete(struct uloop_signal *s);
137
138 bool uloop_cancelling(void);
139
140 static inline void uloop_end(void)
141 {
142 uloop_cancelled = true;
143 }
144
145 int uloop_init(void);
146 int uloop_run_timeout(int timeout);
147 static inline int uloop_run(void)
148 {
149 return uloop_run_timeout(-1);
150 }
151 void uloop_done(void);
152
153 #endif