1 #ifndef INCLUDED_ircd_events_h
2 #define INCLUDED_ircd_events_h
4 * IRC - Internet Relay Chat, include/ircd_events.h
5 * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #ifndef INCLUDED_config_h
27 #ifndef INCLUDED_sys_types_h
28 #include <sys/types.h> /* time_t */
29 #define INCLUDED_sys_types_h
34 typedef void (*EventCallBack)(struct Event*);
37 SS_CONNECTING, /* Connection in progress on socket */
38 SS_LISTENING, /* Socket is a listening socket */
39 SS_CONNECTED, /* Socket is a connected socket */
40 SS_DATAGRAM, /* Socket is a datagram socket */
41 SS_CONNECTDG, /* Socket is a connected datagram socket */
42 SS_NOTSOCK /* Socket isn't a socket at all */
46 TT_ABSOLUTE, /* timer that runs at a specific time */
47 TT_RELATIVE, /* timer that runs so many seconds in the future */
48 TT_PERIODIC /* timer that runs periodically */
52 ET_READ, /* Readable event detected */
53 ET_WRITE, /* Writable event detected */
54 ET_ACCEPT, /* Connection can be accepted */
55 ET_CONNECT, /* Connection completed */
56 ET_EOF, /* End-of-file on connection */
57 ET_ERROR, /* Error condition detected */
58 ET_SIGNAL, /* A signal was received */
59 ET_EXPIRE, /* A timer expired */
60 ET_DESTROY /* The generator is being destroyed */
64 struct GenHeader* gh_next; /* linked list of generators */
65 struct GenHeader** gh_prev_p;
67 struct GenHeader* gh_qnext; /* linked list of generators in queue */
68 struct GenHeader** gh_qprev_p;
69 struct Event* gh_head; /* head of event queue */
70 struct Event* gh_tail; /* tail of event queue */
72 unsigned int gh_flags; /* generator flags */
73 unsigned int gh_ref; /* reference count */
74 EventCallBack gh_call; /* generator callback function */
75 void* gh_data; /* extra data */
77 void* ed_ptr; /* engine data == pointer */
78 int ed_int; /* engine data == integer */
79 } gh_engdata;/* engine data */
82 #define GEN_DESTROY 0x0001 /* generator is to be destroyed */
83 #define GEN_MARKED 0x0002 /* generator is marked for destruction */
84 #define GEN_ACTIVE 0x0004 /* generator is active */
85 #define GEN_READD 0x0008 /* generator (timer) must be re-added */
86 #define GEN_ERROR 0x0010 /* an error occurred on the generator */
89 struct GenHeader s_header; /* generator information */
90 enum SocketState s_state; /* state socket's in */
91 unsigned int s_events; /* events socket is interested in */
92 int s_fd; /* file descriptor for socket */
95 #define SOCK_EVENT_READABLE 0x0001 /* interested in readable */
96 #define SOCK_EVENT_WRITABLE 0x0002 /* interested in writable */
98 #define SOCK_EVENT_MASK (SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE)
100 #define SOCK_ACTION_SET 0x0000 /* set interest set as follows */
101 #define SOCK_ACTION_ADD 0x1000 /* add to interest set */
102 #define SOCK_ACTION_DEL 0x2000 /* remove from interest set */
104 #define SOCK_ACTION_MASK 0x3000 /* mask out the actions */
106 #define s_state(sock) ((sock)->s_state)
107 #define s_events(sock) ((sock)->s_events)
108 #define s_fd(sock) ((sock)->s_fd)
109 #define s_data(sock) ((sock)->s_header.gh_data)
110 #define s_ed_int(sock) ((sock)->s_header.gh_engdata.ed_int)
111 #define s_ed_ptr(sock) ((sock)->s_header.gh_engdata.ed_ptr)
112 #define s_active(sock) ((sock)->s_header.gh_flags & GEN_ACTIVE)
114 /* Note: The socket state overrides the socket event mask; that is, if
115 * it's an SS_CONNECTING socket, the engine selects its own definition
116 * of what that looks like and ignores s_events. s_events is meaningful
117 * only for SS_CONNECTED, SS_DATAGRAM, and SS_CONNECTDG, but may be set
118 * prior to the state transition, if desired.
122 struct GenHeader sig_header; /* generator information */
123 int sig_signal; /* signal number */
126 #define sig_signal(sig) ((sig)->sig_signal)
127 #define sig_data(sig) ((sig)->sig_header.gh_data)
128 #define sig_ed_int(sig) ((sig)->sig_header.gh_engdata.ed_int)
129 #define sig_ed_ptr(sig) ((sig)->sig_header.gh_engdata.ed_ptr)
130 #define sig_active(sig) ((sig)->sig_header.gh_flags & GEN_ACTIVE)
133 struct GenHeader t_header; /* generator information */
134 enum TimerType t_type; /* what type of timer this is */
135 time_t t_value; /* value timer was added with */
136 time_t t_expire; /* time at which timer expires */
139 #define t_type(tim) ((tim)->t_type)
140 #define t_value(tim) ((tim)->t_value)
141 #define t_expire(tim) ((tim)->t_expire)
142 #define t_data(tim) ((tim)->t_header.gh_data)
143 #define t_ed_int(tim) ((tim)->t_header.gh_engdata.ed_int)
144 #define t_ed_ptr(tim) ((tim)->t_header.gh_engdata.ed_ptr)
145 #define t_active(tim) ((tim)->t_header.gh_flags & GEN_ACTIVE)
146 #define t_onqueue(tim) ((tim)->t_header.gh_prev_p)
149 struct Event* ev_next; /* linked list of events on queue */
150 struct Event** ev_prev_p;
151 enum EventType ev_type; /* Event type */
152 int ev_data; /* extra data, like errno value */
154 struct GenHeader* gen_header; /* Generator header */
155 struct Socket* gen_socket; /* Socket generating event */
156 struct Signal* gen_signal; /* Signal generating event */
157 struct Timer* gen_timer; /* Timer generating event */
158 } ev_gen; /* object generating event */
161 #define ev_type(ev) ((ev)->ev_type)
162 #define ev_data(ev) ((ev)->ev_data)
163 #define ev_socket(ev) ((ev)->ev_gen.gen_socket)
164 #define ev_signal(ev) ((ev)->ev_gen.gen_signal)
165 #define ev_timer(ev) ((ev)->ev_gen.gen_timer)
168 struct Socket* g_socket; /* list of socket generators */
169 struct Signal* g_signal; /* list of signal generators */
170 struct Timer* g_timer; /* list of timer generators */
173 /* returns 1 if successfully initialized, 0 if not */
174 typedef int (*EngineInit)(int);
176 /* Tell engine about new signal; set to 0 if engine doesn't know signals */
177 typedef void (*EngineSignal)(struct Signal*);
179 /* Tell engine about new socket */
180 typedef int (*EngineAdd)(struct Socket*);
182 /* Tell engine about socket's new_state */
183 typedef void (*EngineState)(struct Socket*, enum SocketState new_state);
185 /* Tell engine about socket's new_events */
186 typedef void (*EngineEvents)(struct Socket*, unsigned int new_events);
188 /* Tell engine a socket's going away */
189 typedef void (*EngineDelete)(struct Socket*);
191 /* The actual event loop */
192 typedef void (*EngineLoop)(struct Generators*);
195 const char* eng_name; /* a name for the engine */
196 EngineInit eng_init; /* initialize engine */
197 EngineSignal eng_signal; /* express interest in a signal */
198 EngineAdd eng_add; /* express interest in a socket */
199 EngineState eng_state; /* mention a change in state to engine */
200 EngineEvents eng_events; /* express interest in socket events */
201 EngineDelete eng_closing; /* socket is being closed */
202 EngineLoop eng_loop; /* actual event loop */
205 #define gen_ref_inc(gen) (((struct GenHeader*) (gen))->gh_ref++)
206 #define gen_ref_dec(gen) \
208 struct GenHeader* _gen = (struct GenHeader*) (gen); \
209 if (!--_gen->gh_ref && (_gen->gh_flags & GEN_DESTROY)) { \
211 event_generate(ET_DESTROY, _gen, 0); \
214 #define gen_clear_error(gen) \
215 (((struct GenHeader*) (gen))->gh_flags &= ~GEN_ERROR)
217 void gen_dequeue(void* arg);
219 void event_init(int max_sockets);
220 void event_loop(void);
221 void event_generate(enum EventType type, void* arg, int data);
223 struct Timer* timer_init(struct Timer* timer);
224 void timer_add(struct Timer* timer, EventCallBack call, void* data,
225 enum TimerType type, time_t value);
226 void timer_del(struct Timer* timer);
227 void timer_chg(struct Timer* timer, enum TimerType type, time_t value);
228 void timer_run(void);
229 #define timer_next(gen) ((gen)->g_timer ? (gen)->g_timer->t_expire : 0)
231 void signal_add(struct Signal* signal, EventCallBack call, void* data,
234 int socket_add(struct Socket* sock, EventCallBack call, void* data,
235 enum SocketState state, unsigned int events, int fd);
236 void socket_del(struct Socket* sock);
237 void socket_state(struct Socket* sock, enum SocketState state);
238 void socket_events(struct Socket* sock, unsigned int events);
240 const char* engine_name(void);
243 /* These routines pretty-print names for states and types for debug printing */
245 const char* state_to_name(enum SocketState state);
246 const char* timer_to_name(enum TimerType type);
247 const char* event_to_name(enum EventType type);
248 const char* gen_flags(unsigned int flags);
249 const char* sock_flags(unsigned int flags);
251 #endif /* DEBUGMODE */
253 #endif /* INCLUDED_ircd_events_h */