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