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