1 #include "EventAPI.h" 2 3 #define PE_NEWID ('e'+'v') /* for New() macro */ 4 5 #define PE_RING_INIT(LNK, SELF) \ 6 STMT_START { \ 7 (LNK)->next = LNK; \ 8 (LNK)->prev = LNK; \ 9 (LNK)->self = SELF; \ 10 } STMT_END 11 12 #define PE_RING_EMPTY(LNK) ((LNK)->next == LNK) 13 14 #define PE_RING_UNSHIFT(LNK, ALL) \ 15 STMT_START { \ 16 assert((LNK)->next==LNK); \ 17 (LNK)->next = (ALL)->next; \ 18 (LNK)->prev = ALL; \ 19 (LNK)->next->prev = LNK; \ 20 (LNK)->prev->next = LNK; \ 21 } STMT_END 22 23 #define PE_RING_ADD_BEFORE(L1,L2) \ 24 STMT_START { \ 25 assert((L1)->next==L1); \ 26 (L1)->next = L2; \ 27 (L1)->prev = (L2)->prev; \ 28 (L1)->next->prev = L1; \ 29 (L1)->prev->next = L1; \ 30 } STMT_END 31 32 #define PE_RING_DETACH(LNK) \ 33 STMT_START { \ 34 if ((LNK)->next != LNK) { \ 35 (LNK)->next->prev = (LNK)->prev; \ 36 (LNK)->prev->next = (LNK)->next; \ 37 (LNK)->next = LNK; \ 38 } \ 39 } STMT_END 40 41 /* too bad typeof is a G++ specific extension 42 #define PE_RING_POP(ALL, TO) \ 43 STMT_START { \ 44 pe_ring *lk = (ALL)->prev; \ 45 PE_RING_DETACH(lk); \ 46 TO = (typeof(TO)) lk->self; \ 47 } STMT_END 48 */ 49 50 typedef struct pe_cbframe pe_cbframe; 51 struct pe_cbframe { 52 pe_event *ev; 53 IV run_id; 54 void *stats; 55 }; 56 57 typedef struct pe_tied pe_tied; 58 struct pe_tied { 59 pe_watcher base; 60 pe_timeable tm; 61 }; 62 63 #define WKEYMETH(M) static void M(pe_watcher *ev, SV *nval) 64 #define EKEYMETH(M) static void M(pe_event *ev, SV *nval) 65 66 /* When this becomes a public API then we should also publish C interfaces 67 to set up perl & C callbacks. For now we can be lazy. */ 68 struct pe_event_vtbl { 69 HV *stash; 70 pe_event *(*new_event)(pe_watcher *); 71 void (*dtor)(pe_event *); 72 73 pe_ring freelist; 74 }; 75 76 struct pe_watcher_vtbl { 77 int did_require; 78 HV *stash; 79 void (*dtor)(pe_watcher *); 80 char*(*start)(pe_watcher *, int); 81 void (*stop)(pe_watcher *); 82 void (*alarm)(pe_watcher *, pe_timeable *); 83 pe_event_vtbl *event_vtbl; 84 pe_event *(*new_event)(pe_watcher *); 85 }; 86 87 #define PE_ACTIVE 0x001 88 #define PE_POLLING 0x002 89 #define PE_SUSPEND 0x004 90 #define PE_PERLCB 0x020 91 #define PE_RUNNOW 0x040 92 #define PE_TMPERLCB 0x080 93 #define PE_CANCELLED 0x400 94 #define PE_DESTROYED 0x800 95 96 #define PE_VISIBLE_FLAGS (PE_ACTIVE | PE_SUSPEND) 97 98 #ifdef DEBUGGING 99 # define WaDEBUGx(ev) (SvIV(DebugLevel) + WaDEBUG(ev)) 100 #else 101 # define WaDEBUGx(ev) 0 102 #endif 103 104 /* logically waiting for something to happen */ 105 #define WaACTIVE(ev) (WaFLAGS(ev) & PE_ACTIVE) 106 #define WaACTIVE_on(ev) (WaFLAGS(ev) |= PE_ACTIVE) 107 #define WaACTIVE_off(ev) (WaFLAGS(ev) &= ~PE_ACTIVE) 108 109 /* physically registered for poll/select */ 110 #define WaPOLLING(ev) (WaFLAGS(ev) & PE_POLLING) 111 #define WaPOLLING_on(ev) (WaFLAGS(ev) |= PE_POLLING) 112 #define WaPOLLING_off(ev) (WaFLAGS(ev) &= ~PE_POLLING) 113 114 #define WaSUSPEND(ev) (WaFLAGS(ev) & PE_SUSPEND) 115 #define WaSUSPEND_on(ev) (WaFLAGS(ev) |= PE_SUSPEND) 116 #define WaSUSPEND_off(ev) (WaFLAGS(ev) &= ~PE_SUSPEND) 117 118 #define WaPERLCB(ev) (WaFLAGS(ev) & PE_PERLCB) 119 #define WaPERLCB_on(ev) (WaFLAGS(ev) |= PE_PERLCB) 120 #define WaPERLCB_off(ev) (WaFLAGS(ev) &= ~PE_PERLCB) 121 122 #define WaTMPERLCB(ev) (WaFLAGS(ev) & PE_TMPERLCB) 123 #define WaTMPERLCB_on(ev) (WaFLAGS(ev) |= PE_TMPERLCB) 124 #define WaTMPERLCB_off(ev) (WaFLAGS(ev) &= ~PE_TMPERLCB) 125 126 /* RUNNOW should be event specific XXX */ 127 #define WaRUNNOW(ev) (WaFLAGS(ev) & PE_RUNNOW) 128 #define WaRUNNOW_on(ev) (WaFLAGS(ev) |= PE_RUNNOW) 129 #define WaRUNNOW_off(ev) (WaFLAGS(ev) &= ~PE_RUNNOW) 130 131 #define WaCANCELLED(ev) (WaFLAGS(ev) & PE_CANCELLED) 132 #define WaCANCELLED_on(ev) (WaFLAGS(ev) |= PE_CANCELLED) 133 #define WaCANCELLED_off(ev) (WaFLAGS(ev) &= ~PE_CANCELLED) 134 135 #define WaDESTROYED(ev) (WaFLAGS(ev) & PE_DESTROYED) 136 #define WaDESTROYED_on(ev) (WaFLAGS(ev) |= PE_DESTROYED) 137 #define WaDESTROYED_off(ev) (WaFLAGS(ev) &= ~PE_DESTROYED) 138 139 #define WaCANDESTROY(ev) \ 140 (WaCANCELLED(ev) && ev->refcnt == 0 && !ev->mysv) 141 142 143 #define EvFLAGS(ev) ((pe_event*)ev)->flags 144 145 #define EvPERLCB(ev) (EvFLAGS(ev) & PE_PERLCB) 146 #define EvPERLCB_on(ev) (EvFLAGS(ev) |= PE_PERLCB) 147 #define EvPERLCB_off(ev) (EvFLAGS(ev) &= ~PE_PERLCB) 148