static pe_ring Prepare, Check, AsyncCheck, Callback; static void boot_hook() { PE_RING_INIT(&Prepare, 0); PE_RING_INIT(&Check, 0); PE_RING_INIT(&AsyncCheck, 0); PE_RING_INIT(&Callback, 0); } static pe_qcallback * pe_add_hook(char *which, int is_perl, void *cb, void *ext_data) { pe_qcallback *qcb; EvNew(2, qcb, 1, pe_qcallback); PE_RING_INIT(&qcb->ring, qcb); qcb->is_perl = is_perl; if (is_perl) { qcb->callback = SvREFCNT_inc((SV*)cb); qcb->ext_data = 0; } else { qcb->callback = cb; qcb->ext_data = ext_data; } if (strEQ(which, "prepare")) PE_RING_UNSHIFT(&qcb->ring, &Prepare); else if (strEQ(which, "check")) PE_RING_UNSHIFT(&qcb->ring, &Check); else if (strEQ(which, "asynccheck")) PE_RING_UNSHIFT(&qcb->ring, &AsyncCheck); else if (strEQ(which, "callback")) PE_RING_UNSHIFT(&qcb->ring, &Callback); else croak("Unknown hook '%s' in pe_add_hook", which); return qcb; } static pe_qcallback *capi_add_hook(char *which, void *cb, void *ext_data) { return pe_add_hook(which, 0, cb, ext_data); } static void pe_cancel_hook(pe_qcallback *qcb) { if (qcb->is_perl) SvREFCNT_dec((SV*)qcb->callback); PE_RING_DETACH(&qcb->ring); EvFree(2, qcb); } static void pe_map_check(pe_ring *List) { pe_qcallback *qcb = (pe_qcallback*) List->prev->self; while (qcb) { if (qcb->is_perl) { dSP; PUSHMARK(SP); PUTBACK; perl_call_sv((SV*)qcb->callback, G_DISCARD); } else { /* !is_perl */ (* (void(*)(void*)) qcb->callback)(qcb->ext_data); } qcb = (pe_qcallback*) qcb->ring.prev->self; } }