1 #ifndef INCLUDED_ircd_events_h
2 #define INCLUDED_ircd_events_h
3 /*
4  * IRC - Internet Relay Chat, include/ircd_events.h
5  * Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
6  *
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)
10  * any later version.
11  *
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.
16  *
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.
20  */
21 /** @file
22  * @brief Interface and public definitions for event loop.
23  * @version $Id$
24  */
25 
26 #ifndef INCLUDED_config_h
27 #include "config.h"
28 #endif
29 #ifndef INCLUDED_sys_types_h
30 #include <sys/types.h>	/* time_t */
31 #define INCLUDED_sys_types_h
32 #endif
33 
34 struct Event;
35 
36 /** Generic callback for event activity. */
37 typedef void (*EventCallBack)(struct Event*);
38 
39 /** State of a Socket structure. */
40 enum SocketState {
41   SS_CONNECTING,	/**< Connection in progress on socket */
42   SS_LISTENING,		/**< Socket is a listening socket */
43   SS_CONNECTED,		/**< Socket is a connected socket */
44   SS_DATAGRAM,		/**< Socket is a datagram socket */
45   SS_CONNECTDG,		/**< Socket is a connected datagram socket */
46   SS_NOTSOCK		/**< Socket isn't a socket at all */
47 };
48 
49 /** Type of a Timer (how its expiration is measured). */
50 enum TimerType {
51   TT_ABSOLUTE,		/**< timer that runs at a specific time */
52   TT_RELATIVE,		/**< timer that runs so many seconds in the future */
53   TT_PERIODIC		/**< timer that runs periodically */
54 };
55 
56 /** Type of event that generated a callback. */
57 enum EventType {
58   ET_READ,		/**< Readable event detected */
59   ET_WRITE,		/**< Writable event detected */
60   ET_ACCEPT,		/**< Connection can be accepted */
61   ET_CONNECT,		/**< Connection completed */
62   ET_EOF,		/**< End-of-file on connection */
63   ET_ERROR,		/**< Error condition detected */
64   ET_SIGNAL,		/**< A signal was received */
65   ET_EXPIRE,		/**< A timer expired */
66   ET_DESTROY		/**< The generator is being destroyed */
67 };
68 
69 /** Common header for event generators. */
70 struct GenHeader {
71   struct GenHeader*  gh_next;	/**< linked list of generators */
72   struct GenHeader** gh_prev_p; /**< previous pointer to this generator */
73 #ifdef IRCD_THREADED
74   struct GenHeader*  gh_qnext;	/**< linked list of generators in queue */
75   struct GenHeader** gh_qprev_p; /**< previous pointer to this generator */
76   struct Event*	     gh_head;	/**< head of event queue */
77   struct Event*	     gh_tail;	/**< tail of event queue */
78 #endif
79   unsigned int	     gh_flags;	/**< generator flags */
80   unsigned int	     gh_ref;	/**< reference count */
81   EventCallBack	     gh_call;	/**< generator callback function */
82   void*		     gh_data;	/**< extra data */
83   union {
84     void*	     ed_ptr;	/**< engine data as pointer */
85     int		     ed_int;	/**< engine data as integer */
86   }		     gh_engdata;/**< engine data */
87 };
88 
89 #define GEN_DESTROY	0x0001	/**< generator is to be destroyed */
90 #define GEN_MARKED	0x0002	/**< generator is marked for destruction */
91 #define GEN_ACTIVE	0x0004	/**< generator is active */
92 #define GEN_READD	0x0008	/**< generator (timer) must be re-added */
93 #define GEN_ERROR	0x0010	/**< an error occurred on the generator */
94 
95 /** Socket event generator.
96  * Note: The socket state overrides the socket event mask; that is, if
97  * it's an SS_CONNECTING socket, the engine selects its own definition
98  * of what that looks like and ignores s_events.  s_events is meaningful
99  * only for SS_CONNECTED, SS_DATAGRAM, and SS_CONNECTDG, but may be set
100  * prior to the state transition, if desired.
101  */
102 struct Socket {
103   struct GenHeader s_header;	/**< generator information */
104   enum SocketState s_state;	/**< state socket's in */
105   unsigned int	   s_events;	/**< events socket is interested in */
106   int		   s_fd;	/**< file descriptor for socket */
107 };
108 
109 #define SOCK_EVENT_READABLE	0x0001	/**< interested in readable */
110 #define SOCK_EVENT_WRITABLE	0x0002	/**< interested in writable */
111 
112 /** Bitmask of possible event interests for a socket. */
113 #define SOCK_EVENT_MASK		(SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE)
114 
115 #define SOCK_ACTION_SET		0x0000	/**< set interest set as follows */
116 #define SOCK_ACTION_ADD		0x1000	/**< add to interest set */
117 #define SOCK_ACTION_DEL		0x2000	/**< remove from interest set */
118 
119 #define SOCK_ACTION_MASK	0x3000	/**< mask out the actions */
120 
121 /** Retrieve state of the Socket \a sock. */
122 #define s_state(sock)	((sock)->s_state)
123 /** Retrieve interest mask of the Socket \a sock. */
124 #define s_events(sock)	((sock)->s_events)
125 /** Retrieve file descriptor of the Socket \a sock. */
126 #define s_fd(sock)	((sock)->s_fd)
127 /** Retrieve user data pointer of the Socket \a sock. */
128 #define s_data(sock)	((sock)->s_header.gh_data)
129 /** Retrieve engine data integer of the Socket \a sock. */
130 #define s_ed_int(sock)	((sock)->s_header.gh_engdata.ed_int)
131 /** Retrieve engine data pointer of the Socket \a sock. */
132 #define s_ed_ptr(sock)	((sock)->s_header.gh_engdata.ed_ptr)
133 /** Retrieve whether the Socket \a sock is active. */
134 #define s_active(sock)	((sock)->s_header.gh_flags & GEN_ACTIVE)
135 
136 /** Signal event generator. */
137 struct Signal {
138   struct GenHeader sig_header;	/**< generator information */
139   int		   sig_signal;	/**< signal number */
140 };
141 
142 /** Retrieve signal number of the Signal \a sig. */
143 #define sig_signal(sig)	((sig)->sig_signal)
144 /** Retrieve user data pointer of the Signal \a sig. */
145 #define sig_data(sig)	((sig)->sig_header.gh_data)
146 /** Retrieve engine data integer of the Signal \a sig. */
147 #define sig_ed_int(sig)	((sig)->sig_header.gh_engdata.ed_int)
148 /** Retrieve engine data pointer of the Signal \a sig. */
149 #define sig_ed_ptr(sig)	((sig)->sig_header.gh_engdata.ed_ptr)
150 /** Retrieve whether the Signal \a sig is active. */
151 #define sig_active(sig)	((sig)->sig_header.gh_flags & GEN_ACTIVE)
152 
153 /** Timer event generator. */
154 struct Timer {
155   struct GenHeader t_header;	/**< generator information */
156   enum TimerType   t_type;	/**< what type of timer this is */
157   time_t	   t_value;	/**< value timer was added with */
158   time_t	   t_expire;	/**< time at which timer expires */
159 };
160 
161 /** Retrieve type of the Timer \a tim. */
162 #define t_type(tim)	((tim)->t_type)
163 /** Retrieve interval of the Timer \a tim. */
164 #define t_value(tim)	((tim)->t_value)
165 /** Retrieve expiration time of the Timer \a tim. */
166 #define t_expire(tim)	((tim)->t_expire)
167 /** Retrieve user data pointer of the Timer \a tim. */
168 #define t_data(tim)	((tim)->t_header.gh_data)
169 /** Retrieve engine data integer of the Timer \a tim. */
170 #define t_ed_int(tim)	((tim)->t_header.gh_engdata.ed_int)
171 /** Retrieve engine data pointer of the Timer \a tim. */
172 #define t_ed_ptr(tim)	((tim)->t_header.gh_engdata.ed_ptr)
173 /** Retrieve whether the Timer \a tim is active. */
174 #define t_active(tim)	((tim)->t_header.gh_flags & GEN_ACTIVE)
175 /** Retrieve whether the Timer \a tim is enqueued. */
176 #define t_onqueue(tim)	((tim)->t_header.gh_prev_p)
177 
178 /** Event activity descriptor. */
179 struct Event {
180   struct Event*	 ev_next;	/**< linked list of events on queue */
181   struct Event** ev_prev_p;     /**< previous pointer to this event */
182   enum EventType ev_type;	/**< Event type */
183   int		 ev_data;	/**< extra data, like errno value */
184   union {
185     struct GenHeader* gen_header;	/**< Generator header */
186     struct Socket*    gen_socket;	/**< Socket generating event */
187     struct Signal*    gen_signal;	/**< Signal generating event */
188     struct Timer*     gen_timer;	/**< Timer generating event */
189   }		 ev_gen;	/**< object generating event */
190 };
191 
192 /** Retrieve the type of the Event \a ev. */
193 #define ev_type(ev)	((ev)->ev_type)
194 /** Retrieve the extra data of the Event \a ev. */
195 #define ev_data(ev)	((ev)->ev_data)
196 /** Retrieve the Socket that generated the Event \a ev. */
197 #define ev_socket(ev)	((ev)->ev_gen.gen_socket)
198 /** Retrieve the Signal that generated the Event \a ev. */
199 #define ev_signal(ev)	((ev)->ev_gen.gen_signal)
200 /** Retrieve the Timer that generated the Event \a ev. */
201 #define ev_timer(ev)	((ev)->ev_gen.gen_timer)
202 
203 /** List of all event generators. */
204 struct Generators {
205   struct GenHeader* g_socket;	/**< list of socket generators */
206   struct GenHeader* g_signal;	/**< list of signal generators */
207   struct GenHeader* g_timer;	/**< list of timer generators */
208 };
209 
210 /** Returns 1 if successfully initialized, 0 if not.
211  * @param[in] max_sockets Number of sockets to support.
212  */
213 typedef int (*EngineInit)(int max_sockets);
214 
215 /** Tell engine about new signal.
216  * @param[in] sig Signal event generator to add.
217  */
218 typedef void (*EngineSignal)(struct Signal* sig);
219 
220 /** Tell engine about new socket.
221  * @param[in] sock Socket event generator to add.
222  */
223 typedef int (*EngineAdd)(struct Socket* sock);
224 
225 /** Tell engine about socket's new_state.
226  * @param[in] sock Socket whose state is changing.
227  * @param[in] new_state New state for socket.
228  */
229 typedef void (*EngineState)(struct Socket* sock, enum SocketState new_state);
230 
231 /** Tell engine about socket's new event interests.
232  * @param[in] sock Socket whose interest mask is changing.
233  * @param[in] new_events New event mask to set (not SOCK_ACTION_ADD or SOCK_ACTION_DEL).
234  */
235 typedef void (*EngineEvents)(struct Socket* sock, unsigned int new_events);
236 
237 /** Tell engine a socket is going away.
238  * @param[in] sock Socket being destroyed.
239  */
240 typedef void (*EngineDelete)(struct Socket* sock);
241 
242 /** The actual event loop.
243  * @param[in] gens List of event generators.
244  */
245 typedef void (*EngineLoop)(struct Generators* gens);
246 
247 /** Structure for an event engine to describe itself. */
248 struct Engine {
249   const char*	eng_name;	/**< a name for the engine */
250   EngineInit	eng_init;	/**< initialize engine */
251   EngineSignal	eng_signal;	/**< express interest in a signal (may be NULL) */
252   EngineAdd	eng_add;	/**< express interest in a socket */
253   EngineState	eng_state;	/**< mention a change in state to engine */
254   EngineEvents	eng_events;	/**< express interest in socket events */
255   EngineDelete	eng_closing;	/**< socket is being closed */
256   EngineLoop	eng_loop;	/**< actual event loop */
257 };
258 
259 /** Increment the reference count of \a gen. */
260 #define gen_ref_inc(gen)	(((struct GenHeader*) (gen))->gh_ref++)
261 /** Decrement the reference count of \a gen. */
262 #define gen_ref_dec(gen)						      \
263 do {									      \
264   struct GenHeader* _gen = (struct GenHeader*) (gen);			      \
265   if (!--_gen->gh_ref && (_gen->gh_flags & GEN_DESTROY)) {		      \
266     gen_dequeue(_gen);							      \
267     event_generate(ET_DESTROY, _gen, 0);				      \
268   }									      \
269 } while (0)
270 /** Clear the error flag for \a gen. */
271 #define gen_clear_error(gen)						      \
272 	(((struct GenHeader*) (gen))->gh_flags &= ~GEN_ERROR)
273 
274 void gen_dequeue(void* arg);
275 
276 void event_init(int max_sockets);
277 void event_loop(void);
278 void event_generate(enum EventType type, void* arg, int data);
279 
280 struct Timer* timer_init(struct Timer* timer);
281 void timer_add(struct Timer* timer, EventCallBack call, void* data,
282 	       enum TimerType type, time_t value);
283 void timer_del(struct Timer* timer);
284 void timer_chg(struct Timer* timer, enum TimerType type, time_t value);
285 void timer_run(void);
286 /** Retrieve the next timer's expiration time from Generators \a gen. */
287 #define timer_next(gen)	((gen)->g_timer ? ((struct Timer*)(gen)->g_timer)->t_expire : 0)
288 
289 void signal_add(struct Signal* signal, EventCallBack call, void* data,
290 		int sig);
291 
292 int socket_add(struct Socket* sock, EventCallBack call, void* data,
293 	       enum SocketState state, unsigned int events, int fd);
294 void socket_del(struct Socket* sock);
295 void socket_state(struct Socket* sock, enum SocketState state);
296 void socket_events(struct Socket* sock, unsigned int events);
297 
298 const char* engine_name(void);
299 
300 #ifdef DEBUGMODE
301 /* These routines pretty-print names for states and types for debug printing */
302 
303 const char* state_to_name(enum SocketState state);
304 const char* timer_to_name(enum TimerType type);
305 const char* event_to_name(enum EventType type);
306 const char* gen_flags(unsigned int flags);
307 const char* sock_flags(unsigned int flags);
308 
309 #endif /* DEBUGMODE */
310 
311 #endif /* INCLUDED_ircd_events_h */
312