1 #ifndef EVENT_H
2 #define EVENT_H
3
4 #include "vlg.h"
5
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <signal.h>
9
10 #include <timer_q.h>
11
12 #ifdef __linux__
13 # include <sys/prctl.h>
14 #endif
15
16 #ifdef PR_SET_PDEATHSIG
17 # define PROC_CNTL_PDEATHSIG(x1) prctl(PR_SET_PDEATHSIG, x1, 0, 0, 0)
18 #else
19 # define PROC_CNTL_PDEATHSIG(x1) (-1)
20 #endif
21
22 #ifdef __GNUC__
23 # define EVNT__ATTR_UNUSED(x) vstr__UNUSED_ ## x __attribute__((unused))
24 #elif defined(__LCLINT__)
25 # define EVNT__ATTR_UNUSED(x) /*@unused@*/ vstr__UNUSED_ ## x
26 #else
27 # define EVNT__ATTR_UNUSED(x) vstr__UNUSED_ ## x
28 #endif
29
30 #ifdef __GNUC__
31 # define EVNT__ATTR_USED() __attribute__((used))
32 #else
33 # define EVNT__ATTR_USED()
34 #endif
35
36 #ifndef EVNT_COMPILE_INLINE
37 #define EVNT_COMPILE_INLINE 1
38 #endif
39
40 #ifndef EVNT_CONF_NAGLE
41 #define EVNT_CONF_NAGLE FALSE /* configurable */
42 #endif
43
44 #define EVNT_IO_OK 0
45 #define EVNT_IO_READ_EOF 1
46 #define EVNT_IO_READ_FIN 2
47 #define EVNT_IO_READ_ERR 3
48 #define EVNT_IO_SEND_ERR 4
49
50 struct Evnt;
51
52 struct Evnt_cbs
53 {
54 struct Evnt *(*cb_func_accept) (struct Evnt *,
55 int, struct sockaddr *, socklen_t);
56 int (*cb_func_connect) (struct Evnt *);
57 int (*cb_func_recv) (struct Evnt *);
58 int (*cb_func_send) (struct Evnt *);
59 void (*cb_func_free) (struct Evnt *);
60 int (*cb_func_shutdown_r)(struct Evnt *);
61 };
62
63 struct Evnt
64 {
65 struct Evnt *next;
66 struct Evnt *prev;
67
68 struct Evnt_cbs cbs[1];
69
70 unsigned int ind; /* socket poll */
71
72 Vstr_ref *sa_ref;
73
74 Vstr_base *io_r;
75 Vstr_base *io_w;
76
77 struct Evnt *s_next;
78 struct Evnt *c_next;
79
80 Timer_q_node *tm_o;
81
82 struct timeval ctime;
83 struct timeval mtime;
84
85 unsigned long msecs_tm_mtime;
86
87 VSTR_AUTOCONF_uintmax_t prev_bytes_r;
88 struct
89 {
90 unsigned int req_put;
91 unsigned int req_got;
92 VSTR_AUTOCONF_uintmax_t bytes_r;
93 VSTR_AUTOCONF_uintmax_t bytes_w;
94 } acct;
95
96 unsigned int flag_q_accept : 1;
97 unsigned int flag_q_connect : 1;
98 unsigned int flag_q_recv : 1;
99 unsigned int flag_q_send_recv : 1;
100 unsigned int flag_q_none : 1;
101
102 unsigned int flag_q_send_now : 1;
103 unsigned int flag_q_closed : 1;
104
105 unsigned int flag_q_pkt_move : 1;
106
107 unsigned int flag_io_nagle : 1;
108 unsigned int flag_io_cork : 1;
109
110 unsigned int flag_io_filter : 1;
111
112 unsigned int flag_fully_acpt : 1;
113
114 unsigned int io_r_shutdown : 1;
115 unsigned int io_w_shutdown : 1;
116 };
117
118 #if 1 /* ndef VSTR_AUTOCONF_NDEBUG */
119 # define EVNT_SA(x) ((struct sockaddr *)(x)->sa_ref->ptr)
120 # define EVNT_SA_IN4(x) ((struct sockaddr_in *)(x)->sa_ref->ptr)
121 # define EVNT_SA_IN6(x) ((struct sockaddr_in6 *)(x)->sa_ref->ptr)
122 # define EVNT_SA_UN(x) ((struct sockaddr_un *)(x)->sa_ref->ptr)
123 #else
evnt___chk_sa(void * ptr)124 static struct sockaddr *evnt___chk_sa(void *ptr)
125 {
126 struct sockaddr *sa = ptr;
127 if ((sa->sa_family != AF_INET) &&
128 (sa->sa_family != AF_INET6) &&
129 (sa->sa_family != AF_LOCAL))
130 abort();
131 return (sa);
132 }
evnt___chk_in(void * ptr)133 static struct sockaddr *evnt___chk_in(void *ptr)
134 {
135 struct sockaddr_in *sa = ptr;
136 if (sa->sin_family != AF_INET)
137 abort();
138 return (sa);
139 }
evnt___chk_in6(void * ptr)140 static struct sockaddr *evnt___chk_in6(void *ptr)
141 {
142 struct sockaddr_in6 *sa = ptr;
143 if (sa->sin6_family != AF_INET6)
144 abort();
145 return (sa);
146 }
evnt___chk_un(void * ptr)147 static struct sockaddr *evnt___chk_un(void *ptr)
148 {
149 struct sockaddr_un *sa = ptr;
150 if (sa->sun_family != AF_LOCAL)
151 abort();
152 return (sa);
153 }
154
155 # define EVNT_SA(x) evnt___chk_sa((x)->sa_ref->ptr)
156 # define EVNT_SA_IN4(x) evnt___chk_in((x)->sa_ref->ptr)
157 # define EVNT_SA_IN6(x) evnt___chk_in6((x)->sa_ref->ptr)
158 # define EVNT_SA_UN(x) evnt___chk_un((x)->sa_ref->ptr)
159 #endif
160
161 /* FIXME: bad namespace */
162 typedef struct Acpt_data
163 {
164 struct Evnt *evnt;
165 Vstr_ref *sa;
166 } Acpt_data;
167 #if 1 /* ndef VSTR_AUTOCONF_NDEBUG */
168 # define ACPT_SA(x) ((struct sockaddr *)(x)->sa->ptr)
169 # define ACPT_SA_IN4(x) ((struct sockaddr_in *)(x)->sa->ptr)
170 # define ACPT_SA_IN6(x) ((struct sockaddr_in6 *)(x)->sa->ptr)
171 # define ACPT_SA_UN(x) ((struct sockaddr_un *)(x)->sa->ptr)
172 #else
173 # define ACPT_SA(x) evnt___chk_sa((x)->sa->ptr)
174 # define ACPT_SA_IN4(x) evnt___chk_in((x)->sa->ptr)
175 # define ACPT_SA_IN6(x) evnt___chk_in6((x)->sa->ptr)
176 # define ACPT_SA_UN(x) evnt___chk_un((x)->sa->ptr)
177 #endif
178
179 typedef struct Acpt_listener
180 {
181 struct Evnt evnt[1];
182 unsigned int max_connections;
183 Vstr_ref *ref;
184 } Acpt_listener;
185
186 extern volatile sig_atomic_t evnt_child_exited;
187
188 extern int evnt_opt_nagle;
189
190 extern void evnt_logger(Vlg *);
191
192 extern void evnt_fd__set_nonblock(int, int);
193
194 extern int evnt_fd(struct Evnt *);
195
196 extern void evnt_wait_cntl_add(struct Evnt *, int);
197 extern void evnt_wait_cntl_del(struct Evnt *, int);
198
199 extern int evnt_cb_func_connect(struct Evnt *);
200 extern struct Evnt *evnt_cb_func_accept(struct Evnt *,
201 int, struct sockaddr *, socklen_t);
202 extern int evnt_cb_func_recv(struct Evnt *);
203 extern int evnt_cb_func_send(struct Evnt *);
204 extern void evnt_cb_func_free(struct Evnt *);
205 extern void evnt_cb_func_F(struct Evnt *);
206 extern int evnt_cb_func_shutdown_r(struct Evnt *);
207
208 extern int evnt_make_con_ipv4(struct Evnt *, const char *, short);
209 extern int evnt_make_con_local(struct Evnt *, const char *);
210 extern int evnt_make_bind_ipv4(struct Evnt *, const char *, short,unsigned int);
211 extern int evnt_make_bind_local(struct Evnt *, const char *, unsigned int);
212 extern int evnt_make_acpt_ref(struct Evnt *, int, Vstr_ref *);
213 extern int evnt_make_acpt_dup(struct Evnt *, int, struct sockaddr *, socklen_t);
214 extern int evnt_make_custom(struct Evnt *, int, Vstr_ref *, int);
215
216 extern void evnt_free(struct Evnt *);
217 extern void evnt_close(struct Evnt *);
218 extern void evnt_close_all(void);
219
220 extern void evnt_add(struct Evnt **, struct Evnt *);
221 extern void evnt_del(struct Evnt **, struct Evnt *);
222 extern void evnt_put_pkt(struct Evnt *);
223 extern void evnt_got_pkt(struct Evnt *);
224 extern int evnt_shutdown_r(struct Evnt *, int);
225 extern int evnt_shutdown_w(struct Evnt *);
226 extern int evnt_recv(struct Evnt *, unsigned int *);
227 extern int evnt_send(struct Evnt *);
228 extern int evnt_sendfile(struct Evnt *, int,
229 VSTR_AUTOCONF_uintmax_t *, VSTR_AUTOCONF_uintmax_t *,
230 unsigned int *);
231 extern int evnt_sc_read_send(struct Evnt *, int, VSTR_AUTOCONF_uintmax_t *);
232 extern int evnt_send_add(struct Evnt *, int, size_t);
233 extern void evnt_send_del(struct Evnt *);
234 extern void evnt_scan_fds(unsigned int, size_t);
235 extern void evnt_scan_send_fds(void);
236 extern void evnt_scan_q_close(void);
237 extern void evnt_acpt_close_all(void);
238
239
240 extern void evnt_stats_add(struct Evnt *, const struct Evnt *);
241
242 extern unsigned int evnt_num_all(void);
243 extern int evnt_waiting(void);
244
245 extern void evnt_fd_set_cork(struct Evnt *, int);
246 extern void evnt_fd_set_defer_accept(struct Evnt *, int);
247 extern int evnt_fd_set_filter(struct Evnt *, const char *);
248
249 extern void evnt_timeout_init(void);
250 extern void evnt_timeout_exit(void);
251
252 extern pid_t evnt_make_child(void);
253 extern int evnt_is_child(void);
254 extern int evnt_child_block_beg(void);
255 extern int evnt_child_block_end(void);
256
257 extern int evnt_sc_timeout_via_mtime(struct Evnt *, unsigned long);
258 extern void evnt_sc_main_loop(size_t);
259
260 extern time_t evnt_sc_time(void);
261
262 extern void evnt_sc_serv_cb_func_acpt_free(struct Evnt *);
263 extern struct Evnt *evnt_sc_serv_make_bind(const char *, unsigned short,
264 unsigned int, unsigned int,
265 unsigned int, const char *);
266
267 extern void evnt_vlg_stats_info(struct Evnt *, const char *);
268
269 extern int evnt_poll_init(void);
270 extern int evnt_poll_direct_enabled(void);
271 extern int evnt_poll_child_init(void);
272
273 extern unsigned int evnt_poll_add(struct Evnt *, int);
274 extern void evnt_poll_del(struct Evnt *);
275 extern int evnt_poll_swap_accept_read(struct Evnt *, int);
276 extern int evnt_poll(void);
277
278 extern struct Evnt *evnt_find_least_used(void);
279
280 extern struct Evnt *evnt_queue(const char *);
281
282 extern void evnt_out_dbg3(const char *);
283
284 #endif
285