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