1 #ifndef _event_api_H_ 2 #define _event_api_H_ 3 4 /* 5 The API for the operating system dictates which events are 6 truly asyncronous. Event needs C-level support only for 7 these types of events. 8 */ 9 10 typedef struct pe_watcher_vtbl pe_watcher_vtbl; 11 typedef struct pe_watcher pe_watcher; 12 typedef struct pe_event_vtbl pe_event_vtbl; 13 typedef struct pe_event pe_event; 14 typedef struct pe_ring pe_ring; 15 16 struct pe_ring { void *self; pe_ring *next, *prev; }; 17 18 struct pe_watcher { 19 pe_watcher_vtbl *vtbl; 20 SV *mysv; 21 NV cbtime; /* float? XXX */ 22 void *callback; 23 void *ext_data; 24 void *stats; 25 int running; /* SAVEINT */ 26 U32 flags; 27 SV *desc; 28 pe_ring all; /* all watchers */ 29 pe_ring events; /* this watcher's queued events */ 30 HV *FALLBACK; 31 I16 refcnt; /* internal to Event; not perl related */ 32 I16 prio; 33 I16 max_cb_tm; 34 }; 35 36 struct pe_event { 37 pe_event_vtbl *vtbl; 38 SV *mysv; 39 pe_watcher *up; 40 U32 flags; 41 void *callback; 42 void *ext_data; 43 pe_ring peer; /* homogeneous */ 44 pe_ring que; /* heterogeneous */ 45 I16 hits; 46 I16 prio; 47 }; 48 49 /* This must be placed directly after pe_watcher so the memory 50 layouts are always compatible. XXX? */ 51 typedef struct pe_timeable pe_timeable; 52 struct pe_timeable { 53 pe_ring ring; 54 NV at; 55 }; 56 57 typedef struct pe_qcallback pe_qcallback; 58 struct pe_qcallback { 59 pe_ring ring; 60 int is_perl; 61 void *callback; 62 void *ext_data; 63 }; 64 65 /* PUBLIC FLAGS */ 66 #define PE_REENTRANT 0x0008 67 #define PE_HARD 0x0010 68 #define PE_DEBUG 0x1000 69 #define PE_REPEAT 0x2000 70 #define PE_INVOKE1 0x4000 71 72 #define WaFLAGS(ev) ((pe_watcher*)ev)->flags 73 74 #define WaDEBUG(ev) ((WaFLAGS(ev) & PE_DEBUG)? 2:0) /*arthimetical*/ 75 #define WaDEBUG_on(ev) (WaFLAGS(ev) |= PE_DEBUG) 76 #define WaDEBUG_off(ev) (WaFLAGS(ev) &= ~PE_DEBUG) 77 78 #define WaREPEAT(ev) (WaFLAGS(ev) & PE_REPEAT) 79 #define WaREPEAT_on(ev) (WaFLAGS(ev) |= PE_REPEAT) 80 #define WaREPEAT_off(ev) (WaFLAGS(ev) &= ~PE_REPEAT) 81 82 #define WaREENTRANT(ev) (WaFLAGS(ev) & PE_REENTRANT) 83 #define WaREENTRANT_on(ev) (WaFLAGS(ev) |= PE_REENTRANT) 84 #define WaREENTRANT_off(ev) (WaFLAGS(ev) &= ~PE_REENTRANT) 85 86 #define WaHARD(ev) (WaFLAGS(ev) & PE_HARD) 87 #define WaHARD_on(ev) (WaFLAGS(ev) |= PE_HARD) /* :-) */ 88 #define WaHARD_off(ev) (WaFLAGS(ev) &= ~PE_HARD) 89 90 #define WaINVOKE1(ev) (WaFLAGS(ev) & PE_INVOKE1) 91 #define WaINVOKE1_on(ev) (WaFLAGS(ev) |= PE_INVOKE1) 92 #define WaINVOKE1_off(ev) (WaFLAGS(ev) &= ~PE_INVOKE1) 93 94 /* QUEUE INFO */ 95 #define PE_QUEUES 7 /* Hard to imagine a need for more than 7 queues... */ 96 #define PE_PRIO_HIGH 2 97 #define PE_PRIO_NORMAL 4 98 99 /* io-ish flags */ 100 #define PE_R 0x1 101 #define PE_W 0x2 102 #define PE_E 0x4 103 #define PE_T 0x8 104 105 typedef struct pe_ioevent pe_ioevent; 106 struct pe_ioevent { 107 pe_event base; 108 U16 got; 109 }; 110 111 typedef struct pe_datafulevent pe_datafulevent; 112 struct pe_datafulevent { 113 pe_event base; 114 SV *data; 115 }; 116 117 typedef struct pe_idle pe_idle; 118 struct pe_idle { 119 pe_watcher base; 120 pe_timeable tm; 121 pe_ring iring; 122 SV *max_interval, *min_interval; 123 }; 124 125 typedef struct pe_io pe_io; 126 struct pe_io { 127 pe_watcher base; 128 pe_timeable tm; /*timeout*/ 129 pe_ring ioring; 130 SV *handle; 131 void *tm_callback; 132 void *tm_ext_data; 133 float timeout; 134 U16 poll; 135 /* ifdef UNIX */ 136 int fd; 137 int xref; /*private: for poll*/ 138 /* endif */ 139 }; 140 141 typedef struct pe_signal pe_signal; 142 struct pe_signal { 143 pe_watcher base; 144 pe_ring sring; 145 IV signal; 146 }; 147 148 typedef struct pe_timer pe_timer; 149 struct pe_timer { 150 pe_watcher base; 151 pe_timeable tm; 152 SV *interval; 153 }; 154 155 typedef struct pe_var pe_var; 156 struct pe_var { 157 pe_watcher base; 158 SV *variable; 159 U16 events; 160 }; 161 162 typedef struct pe_group pe_group; 163 struct pe_group { 164 pe_watcher base; 165 NV since; 166 pe_timeable tm; 167 SV *timeout; 168 int members; 169 pe_watcher **member; 170 }; 171 172 typedef struct pe_generic pe_generic; 173 struct pe_generic { 174 pe_watcher base; 175 SV *source; 176 pe_ring active; 177 }; 178 179 typedef struct pe_genericsrc pe_genericsrc; 180 struct pe_genericsrc { 181 SV *mysv; 182 pe_ring watchers; 183 }; 184 185 typedef struct pe_event_stats_vtbl pe_event_stats_vtbl; 186 struct pe_event_stats_vtbl { 187 int on; 188 /* if frame == -1 then we are timing pe_multiplex */ 189 void*(*enter)(int frame, int max_tm); 190 void (*suspend)(void *); 191 void (*resume)(void *); 192 void (*commit)(void *, pe_watcher *); /* callback finished OK */ 193 void (*scrub)(void *, pe_watcher *); /* callback died */ 194 void (*dtor)(void *); 195 }; 196 197 struct EventAPI { 198 #define EventAPI_VERSION 22 199 I32 Ver; 200 201 /* EVENTS */ 202 void (*queue )(pe_event *ev); 203 void (*start )(pe_watcher *ev, int repeat); 204 void (*now )(pe_watcher *ev); 205 void (*stop )(pe_watcher *ev, int cancel_events); 206 void (*cancel )(pe_watcher *ev); 207 void (*suspend )(pe_watcher *ev); 208 void (*resume )(pe_watcher *ev); 209 210 /* All constructors optionally take a stash and template. Either 211 or both can be NULL. The template should not be a reference. */ 212 pe_idle *(*new_idle )(HV*, SV*); 213 pe_timer *(*new_timer )(HV*, SV*); 214 pe_io *(*new_io )(HV*, SV*); 215 pe_var *(*new_var )(HV*, SV*); 216 pe_signal *(*new_signal)(HV*, SV*); 217 218 /* TIMEABLE */ 219 NV (*NVtime)(); 220 void (*tstart)(pe_timeable *); 221 void (*tstop)(pe_timeable *); 222 223 /* HOOKS */ 224 pe_qcallback *(*add_hook)(char *which, void *cb, void *ext_data); 225 void (*cancel_hook)(pe_qcallback *qcb); 226 227 /* STATS */ 228 void (*install_stats)(pe_event_stats_vtbl *esvtbl); 229 void (*collect_stats)(int yes); 230 pe_ring *AllWatchers; 231 232 /* TYPEMAP */ 233 SV *(*watcher_2sv)(pe_watcher *wa); 234 void *(*sv_2watcher)(SV *sv); 235 SV *(*event_2sv)(pe_event *ev); 236 void *(*sv_2event)(SV *sv); 237 int (*sv_2interval)(char *label, SV *in, NV *out); 238 SV *(*events_mask_2sv)(int mask); 239 int (*sv_2events_mask)(SV *sv, int bits); 240 241 /* EVERYTHING ELSE */ 242 void (*unloop)(SV *); 243 void (*unloop_all)(SV *); 244 }; 245 246 static struct EventAPI *GEventAPI=0; 247 248 #define I_EVENT_API(YourName) \ 249 STMT_START { \ 250 SV *sv = perl_get_sv("Event::API",0); \ 251 if (!sv) croak("Event::API not found"); \ 252 GEventAPI = (struct EventAPI*) SvIV(sv); \ 253 if (GEventAPI->Ver != EventAPI_VERSION) { \ 254 croak("Event::API version mismatch (%d != %d) -- please recompile %s", \ 255 GEventAPI->Ver, EventAPI_VERSION, YourName); \ 256 } \ 257 } STMT_END 258 259 #endif 260