1*e2d15004SDag-Erling Smørgrav /* 2*e2d15004SDag-Erling Smørgrav * util/ub_event.c - directly call libevent (compatability) functions 3*e2d15004SDag-Erling Smørgrav * 4*e2d15004SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5*e2d15004SDag-Erling Smørgrav * 6*e2d15004SDag-Erling Smørgrav * This software is open source. 7*e2d15004SDag-Erling Smørgrav * 8*e2d15004SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9*e2d15004SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10*e2d15004SDag-Erling Smørgrav * are met: 11*e2d15004SDag-Erling Smørgrav * 12*e2d15004SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13*e2d15004SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14*e2d15004SDag-Erling Smørgrav * 15*e2d15004SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16*e2d15004SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17*e2d15004SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18*e2d15004SDag-Erling Smørgrav * 19*e2d15004SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20*e2d15004SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21*e2d15004SDag-Erling Smørgrav * specific prior written permission. 22*e2d15004SDag-Erling Smørgrav * 23*e2d15004SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24*e2d15004SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25*e2d15004SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26*e2d15004SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27*e2d15004SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28*e2d15004SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29*e2d15004SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30*e2d15004SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31*e2d15004SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32*e2d15004SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33*e2d15004SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34*e2d15004SDag-Erling Smørgrav */ 35*e2d15004SDag-Erling Smørgrav 36*e2d15004SDag-Erling Smørgrav /** 37*e2d15004SDag-Erling Smørgrav * \file 38*e2d15004SDag-Erling Smørgrav * 39*e2d15004SDag-Erling Smørgrav * This file contains and implementation for the indirection layer for pluggable 40*e2d15004SDag-Erling Smørgrav * events that transparently passes it either directly to libevent, or calls 41*e2d15004SDag-Erling Smørgrav * the libevent compatibility layer functions. 42*e2d15004SDag-Erling Smørgrav */ 43*e2d15004SDag-Erling Smørgrav #include "config.h" 44*e2d15004SDag-Erling Smørgrav #include <sys/time.h> 45*e2d15004SDag-Erling Smørgrav #include "util/ub_event.h" 46*e2d15004SDag-Erling Smørgrav #include "util/log.h" 47*e2d15004SDag-Erling Smørgrav #include "util/netevent.h" 48*e2d15004SDag-Erling Smørgrav #include "util/tube.h" 49*e2d15004SDag-Erling Smørgrav 50*e2d15004SDag-Erling Smørgrav /* We define libevent structures here to hide the libevent stuff. */ 51*e2d15004SDag-Erling Smørgrav 52*e2d15004SDag-Erling Smørgrav #ifdef USE_MINI_EVENT 53*e2d15004SDag-Erling Smørgrav # ifdef USE_WINSOCK 54*e2d15004SDag-Erling Smørgrav # include "util/winsock_event.h" 55*e2d15004SDag-Erling Smørgrav # else 56*e2d15004SDag-Erling Smørgrav # include "util/mini_event.h" 57*e2d15004SDag-Erling Smørgrav # endif /* USE_WINSOCK */ 58*e2d15004SDag-Erling Smørgrav #else /* USE_MINI_EVENT */ 59*e2d15004SDag-Erling Smørgrav /* we use libevent */ 60*e2d15004SDag-Erling Smørgrav # ifdef HAVE_EVENT_H 61*e2d15004SDag-Erling Smørgrav # include <event.h> 62*e2d15004SDag-Erling Smørgrav # else 63*e2d15004SDag-Erling Smørgrav # include "event2/event.h" 64*e2d15004SDag-Erling Smørgrav # include "event2/event_struct.h" 65*e2d15004SDag-Erling Smørgrav # include "event2/event_compat.h" 66*e2d15004SDag-Erling Smørgrav # endif 67*e2d15004SDag-Erling Smørgrav #endif /* USE_MINI_EVENT */ 68*e2d15004SDag-Erling Smørgrav 69*e2d15004SDag-Erling Smørgrav #if UB_EV_TIMEOUT != EV_TIMEOUT || UB_EV_READ != EV_READ || \ 70*e2d15004SDag-Erling Smørgrav UB_EV_WRITE != EV_WRITE || UB_EV_SIGNAL != EV_SIGNAL || \ 71*e2d15004SDag-Erling Smørgrav UB_EV_PERSIST != EV_PERSIST 72*e2d15004SDag-Erling Smørgrav /* Only necessary for libev */ 73*e2d15004SDag-Erling Smørgrav # define NATIVE_BITS(b) ( \ 74*e2d15004SDag-Erling Smørgrav (((b) & UB_EV_TIMEOUT) ? EV_TIMEOUT : 0) \ 75*e2d15004SDag-Erling Smørgrav | (((b) & UB_EV_READ ) ? EV_READ : 0) \ 76*e2d15004SDag-Erling Smørgrav | (((b) & UB_EV_WRITE ) ? EV_WRITE : 0) \ 77*e2d15004SDag-Erling Smørgrav | (((b) & UB_EV_SIGNAL ) ? EV_SIGNAL : 0) \ 78*e2d15004SDag-Erling Smørgrav | (((b) & UB_EV_PERSIST) ? EV_PERSIST : 0)) 79*e2d15004SDag-Erling Smørgrav 80*e2d15004SDag-Erling Smørgrav # define UB_EV_BITS(b) ( \ 81*e2d15004SDag-Erling Smørgrav (((b) & EV_TIMEOUT) ? UB_EV_TIMEOUT : 0) \ 82*e2d15004SDag-Erling Smørgrav | (((b) & EV_READ ) ? UB_EV_READ : 0) \ 83*e2d15004SDag-Erling Smørgrav | (((b) & EV_WRITE ) ? UB_EV_WRITE : 0) \ 84*e2d15004SDag-Erling Smørgrav | (((b) & EV_SIGNAL ) ? UB_EV_SIGNAL : 0) \ 85*e2d15004SDag-Erling Smørgrav | (((b) & EV_PERSIST) ? UB_EV_PERSIST : 0)) 86*e2d15004SDag-Erling Smørgrav 87*e2d15004SDag-Erling Smørgrav # define UB_EV_BITS_CB(C) void my_ ## C (int fd, short bits, void *arg) \ 88*e2d15004SDag-Erling Smørgrav { (C)(fd, UB_EV_BITS(bits), arg); } 89*e2d15004SDag-Erling Smørgrav 90*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_point_udp_callback); 91*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_point_udp_ancil_callback) 92*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_point_tcp_accept_callback) 93*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_point_tcp_handle_callback) 94*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_timer_callback) 95*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_signal_callback) 96*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_point_local_handle_callback) 97*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_point_raw_handle_callback) 98*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(tube_handle_signal) 99*e2d15004SDag-Erling Smørgrav UB_EV_BITS_CB(comm_base_handle_slow_accept) 100*e2d15004SDag-Erling Smørgrav 101*e2d15004SDag-Erling Smørgrav static void (*NATIVE_BITS_CB(void (*cb)(int, short, void*)))(int, short, void*) 102*e2d15004SDag-Erling Smørgrav { 103*e2d15004SDag-Erling Smørgrav if(cb == comm_point_udp_callback) 104*e2d15004SDag-Erling Smørgrav return my_comm_point_udp_callback; 105*e2d15004SDag-Erling Smørgrav else if(cb == comm_point_udp_ancil_callback) 106*e2d15004SDag-Erling Smørgrav return my_comm_point_udp_ancil_callback; 107*e2d15004SDag-Erling Smørgrav else if(cb == comm_point_tcp_accept_callback) 108*e2d15004SDag-Erling Smørgrav return my_comm_point_tcp_accept_callback; 109*e2d15004SDag-Erling Smørgrav else if(cb == comm_point_tcp_handle_callback) 110*e2d15004SDag-Erling Smørgrav return my_comm_point_tcp_handle_callback; 111*e2d15004SDag-Erling Smørgrav else if(cb == comm_timer_callback) 112*e2d15004SDag-Erling Smørgrav return my_comm_timer_callback; 113*e2d15004SDag-Erling Smørgrav else if(cb == comm_signal_callback) 114*e2d15004SDag-Erling Smørgrav return my_comm_signal_callback; 115*e2d15004SDag-Erling Smørgrav else if(cb == comm_point_local_handle_callback) 116*e2d15004SDag-Erling Smørgrav return my_comm_point_local_handle_callback; 117*e2d15004SDag-Erling Smørgrav else if(cb == comm_point_raw_handle_callback) 118*e2d15004SDag-Erling Smørgrav return my_comm_point_raw_handle_callback; 119*e2d15004SDag-Erling Smørgrav else if(cb == tube_handle_signal) 120*e2d15004SDag-Erling Smørgrav return my_tube_handle_signal; 121*e2d15004SDag-Erling Smørgrav else if(cb == comm_base_handle_slow_accept) 122*e2d15004SDag-Erling Smørgrav return my_comm_base_handle_slow_accept; 123*e2d15004SDag-Erling Smørgrav else 124*e2d15004SDag-Erling Smørgrav return NULL; 125*e2d15004SDag-Erling Smørgrav } 126*e2d15004SDag-Erling Smørgrav #else 127*e2d15004SDag-Erling Smørgrav # define NATIVE_BITS(b) (b) 128*e2d15004SDag-Erling Smørgrav # define NATIVE_BITS_CB(c) (c) 129*e2d15004SDag-Erling Smørgrav #endif 130*e2d15004SDag-Erling Smørgrav 131*e2d15004SDag-Erling Smørgrav #ifndef EVFLAG_AUTO 132*e2d15004SDag-Erling Smørgrav #define EVFLAG_AUTO 0 133*e2d15004SDag-Erling Smørgrav #endif 134*e2d15004SDag-Erling Smørgrav 135*e2d15004SDag-Erling Smørgrav #define AS_EVENT_BASE(x) \ 136*e2d15004SDag-Erling Smørgrav (((union {struct ub_event_base* a; struct event_base* b;})x).b) 137*e2d15004SDag-Erling Smørgrav #define AS_UB_EVENT_BASE(x) \ 138*e2d15004SDag-Erling Smørgrav (((union {struct event_base* a; struct ub_event_base* b;})x).b) 139*e2d15004SDag-Erling Smørgrav #define AS_EVENT(x) \ 140*e2d15004SDag-Erling Smørgrav (((union {struct ub_event* a; struct event* b;})x).b) 141*e2d15004SDag-Erling Smørgrav #define AS_UB_EVENT(x) \ 142*e2d15004SDag-Erling Smørgrav (((union {struct event* a; struct ub_event* b;})x).b) 143*e2d15004SDag-Erling Smørgrav 144*e2d15004SDag-Erling Smørgrav const char* ub_event_get_version() 145*e2d15004SDag-Erling Smørgrav { 146*e2d15004SDag-Erling Smørgrav return event_get_version(); 147*e2d15004SDag-Erling Smørgrav } 148*e2d15004SDag-Erling Smørgrav 149*e2d15004SDag-Erling Smørgrav #if (defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && defined(EVBACKEND_SELECT) 150*e2d15004SDag-Erling Smørgrav static const char* ub_ev_backend2str(int b) 151*e2d15004SDag-Erling Smørgrav { 152*e2d15004SDag-Erling Smørgrav switch(b) { 153*e2d15004SDag-Erling Smørgrav case EVBACKEND_SELECT: return "select"; 154*e2d15004SDag-Erling Smørgrav case EVBACKEND_POLL: return "poll"; 155*e2d15004SDag-Erling Smørgrav case EVBACKEND_EPOLL: return "epoll"; 156*e2d15004SDag-Erling Smørgrav case EVBACKEND_KQUEUE: return "kqueue"; 157*e2d15004SDag-Erling Smørgrav case EVBACKEND_DEVPOLL: return "devpoll"; 158*e2d15004SDag-Erling Smørgrav case EVBACKEND_PORT: return "evport"; 159*e2d15004SDag-Erling Smørgrav } 160*e2d15004SDag-Erling Smørgrav return "unknown"; 161*e2d15004SDag-Erling Smørgrav } 162*e2d15004SDag-Erling Smørgrav #endif 163*e2d15004SDag-Erling Smørgrav 164*e2d15004SDag-Erling Smørgrav void 165*e2d15004SDag-Erling Smørgrav ub_get_event_sys(struct ub_event_base* base, const char** n, const char** s, 166*e2d15004SDag-Erling Smørgrav const char** m) 167*e2d15004SDag-Erling Smørgrav { 168*e2d15004SDag-Erling Smørgrav #ifdef USE_WINSOCK 169*e2d15004SDag-Erling Smørgrav (void)base; 170*e2d15004SDag-Erling Smørgrav *n = "event"; 171*e2d15004SDag-Erling Smørgrav *s = "winsock"; 172*e2d15004SDag-Erling Smørgrav *m = "WSAWaitForMultipleEvents"; 173*e2d15004SDag-Erling Smørgrav #elif defined(USE_MINI_EVENT) 174*e2d15004SDag-Erling Smørgrav (void)base; 175*e2d15004SDag-Erling Smørgrav *n = "mini-event"; 176*e2d15004SDag-Erling Smørgrav *s = "internal"; 177*e2d15004SDag-Erling Smørgrav *m = "select"; 178*e2d15004SDag-Erling Smørgrav #else 179*e2d15004SDag-Erling Smørgrav struct event_base* b = AS_EVENT_BASE(base); 180*e2d15004SDag-Erling Smørgrav *s = event_get_version(); 181*e2d15004SDag-Erling Smørgrav # if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP) 182*e2d15004SDag-Erling Smørgrav *n = "libev"; 183*e2d15004SDag-Erling Smørgrav if (!b) 184*e2d15004SDag-Erling Smørgrav b = (struct event_base*)ev_default_loop(EVFLAG_AUTO); 185*e2d15004SDag-Erling Smørgrav # ifdef EVBACKEND_SELECT 186*e2d15004SDag-Erling Smørgrav *m = ub_ev_backend2str(ev_backend((struct ev_loop*)b)); 187*e2d15004SDag-Erling Smørgrav # else 188*e2d15004SDag-Erling Smørgrav *m = "not obtainable"; 189*e2d15004SDag-Erling Smørgrav # endif 190*e2d15004SDag-Erling Smørgrav # elif defined(HAVE_EVENT_BASE_GET_METHOD) 191*e2d15004SDag-Erling Smørgrav *n = "libevent"; 192*e2d15004SDag-Erling Smørgrav if (!b) 193*e2d15004SDag-Erling Smørgrav b = event_base_new(); 194*e2d15004SDag-Erling Smørgrav *m = event_base_get_method(b); 195*e2d15004SDag-Erling Smørgrav # else 196*e2d15004SDag-Erling Smørgrav *n = "unknown"; 197*e2d15004SDag-Erling Smørgrav *m = "not obtainable"; 198*e2d15004SDag-Erling Smørgrav (void)b; 199*e2d15004SDag-Erling Smørgrav # endif 200*e2d15004SDag-Erling Smørgrav # ifdef HAVE_EVENT_BASE_FREE 201*e2d15004SDag-Erling Smørgrav if (b && b != AS_EVENT_BASE(base)) 202*e2d15004SDag-Erling Smørgrav event_base_free(b); 203*e2d15004SDag-Erling Smørgrav # endif 204*e2d15004SDag-Erling Smørgrav #endif 205*e2d15004SDag-Erling Smørgrav } 206*e2d15004SDag-Erling Smørgrav 207*e2d15004SDag-Erling Smørgrav struct ub_event_base* 208*e2d15004SDag-Erling Smørgrav ub_default_event_base(int sigs, time_t* time_secs, struct timeval* time_tv) 209*e2d15004SDag-Erling Smørgrav { 210*e2d15004SDag-Erling Smørgrav void* base; 211*e2d15004SDag-Erling Smørgrav 212*e2d15004SDag-Erling Smørgrav (void)base; 213*e2d15004SDag-Erling Smørgrav #ifdef USE_MINI_EVENT 214*e2d15004SDag-Erling Smørgrav (void)sigs; 215*e2d15004SDag-Erling Smørgrav /* use mini event time-sharing feature */ 216*e2d15004SDag-Erling Smørgrav base = event_init(time_secs, time_tv); 217*e2d15004SDag-Erling Smørgrav #else 218*e2d15004SDag-Erling Smørgrav (void)time_secs; 219*e2d15004SDag-Erling Smørgrav (void)time_tv; 220*e2d15004SDag-Erling Smørgrav # if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP) 221*e2d15004SDag-Erling Smørgrav /* libev */ 222*e2d15004SDag-Erling Smørgrav if(sigs) 223*e2d15004SDag-Erling Smørgrav base = ev_default_loop(EVFLAG_AUTO); 224*e2d15004SDag-Erling Smørgrav else 225*e2d15004SDag-Erling Smørgrav base = ev_loop_new(EVFLAG_AUTO); 226*e2d15004SDag-Erling Smørgrav # else 227*e2d15004SDag-Erling Smørgrav (void)sigs; 228*e2d15004SDag-Erling Smørgrav # ifdef HAVE_EVENT_BASE_NEW 229*e2d15004SDag-Erling Smørgrav base = event_base_new(); 230*e2d15004SDag-Erling Smørgrav # else 231*e2d15004SDag-Erling Smørgrav base = event_init(); 232*e2d15004SDag-Erling Smørgrav # endif 233*e2d15004SDag-Erling Smørgrav # endif 234*e2d15004SDag-Erling Smørgrav #endif 235*e2d15004SDag-Erling Smørgrav return (struct ub_event_base*)base; 236*e2d15004SDag-Erling Smørgrav } 237*e2d15004SDag-Erling Smørgrav 238*e2d15004SDag-Erling Smørgrav struct ub_event_base * 239*e2d15004SDag-Erling Smørgrav ub_libevent_event_base(struct event_base* libevent_base) 240*e2d15004SDag-Erling Smørgrav { 241*e2d15004SDag-Erling Smørgrav #ifdef USE_MINI_EVENT 242*e2d15004SDag-Erling Smørgrav (void)libevent_base; 243*e2d15004SDag-Erling Smørgrav return NULL; 244*e2d15004SDag-Erling Smørgrav #else 245*e2d15004SDag-Erling Smørgrav return AS_UB_EVENT_BASE(libevent_base); 246*e2d15004SDag-Erling Smørgrav #endif 247*e2d15004SDag-Erling Smørgrav } 248*e2d15004SDag-Erling Smørgrav 249*e2d15004SDag-Erling Smørgrav struct event_base * 250*e2d15004SDag-Erling Smørgrav ub_libevent_get_event_base(struct ub_event_base* base) 251*e2d15004SDag-Erling Smørgrav { 252*e2d15004SDag-Erling Smørgrav #ifdef USE_MINI_EVENT 253*e2d15004SDag-Erling Smørgrav (void)base; 254*e2d15004SDag-Erling Smørgrav return NULL; 255*e2d15004SDag-Erling Smørgrav #else 256*e2d15004SDag-Erling Smørgrav return AS_EVENT_BASE(base); 257*e2d15004SDag-Erling Smørgrav #endif 258*e2d15004SDag-Erling Smørgrav } 259*e2d15004SDag-Erling Smørgrav 260*e2d15004SDag-Erling Smørgrav void 261*e2d15004SDag-Erling Smørgrav ub_event_base_free(struct ub_event_base* base) 262*e2d15004SDag-Erling Smørgrav { 263*e2d15004SDag-Erling Smørgrav #ifdef USE_MINI_EVENT 264*e2d15004SDag-Erling Smørgrav event_base_free(AS_EVENT_BASE(base)); 265*e2d15004SDag-Erling Smørgrav #elif defined(HAVE_EVENT_BASE_FREE) && defined(HAVE_EVENT_BASE_ONCE) 266*e2d15004SDag-Erling Smørgrav /* only libevent 1.2+ has it, but in 1.2 it is broken - 267*e2d15004SDag-Erling Smørgrav assertion fails on signal handling ev that is not deleted 268*e2d15004SDag-Erling Smørgrav in libevent 1.3c (event_base_once appears) this is fixed. */ 269*e2d15004SDag-Erling Smørgrav event_base_free(AS_EVENT_BASE(base)); 270*e2d15004SDag-Erling Smørgrav #else 271*e2d15004SDag-Erling Smørgrav (void)base; 272*e2d15004SDag-Erling Smørgrav #endif /* HAVE_EVENT_BASE_FREE and HAVE_EVENT_BASE_ONCE */ 273*e2d15004SDag-Erling Smørgrav } 274*e2d15004SDag-Erling Smørgrav 275*e2d15004SDag-Erling Smørgrav int 276*e2d15004SDag-Erling Smørgrav ub_event_base_dispatch(struct ub_event_base* base) 277*e2d15004SDag-Erling Smørgrav { 278*e2d15004SDag-Erling Smørgrav return event_base_dispatch(AS_EVENT_BASE(base)); 279*e2d15004SDag-Erling Smørgrav } 280*e2d15004SDag-Erling Smørgrav 281*e2d15004SDag-Erling Smørgrav int 282*e2d15004SDag-Erling Smørgrav ub_event_base_loopexit(struct ub_event_base* base) 283*e2d15004SDag-Erling Smørgrav { 284*e2d15004SDag-Erling Smørgrav return event_base_loopexit(AS_EVENT_BASE(base), NULL); 285*e2d15004SDag-Erling Smørgrav } 286*e2d15004SDag-Erling Smørgrav 287*e2d15004SDag-Erling Smørgrav struct ub_event* 288*e2d15004SDag-Erling Smørgrav ub_event_new(struct ub_event_base* base, int fd, short bits, 289*e2d15004SDag-Erling Smørgrav void (*cb)(int, short, void*), void* arg) 290*e2d15004SDag-Erling Smørgrav { 291*e2d15004SDag-Erling Smørgrav struct event *ev = (struct event*)calloc(1, sizeof(struct event)); 292*e2d15004SDag-Erling Smørgrav 293*e2d15004SDag-Erling Smørgrav if (!ev) 294*e2d15004SDag-Erling Smørgrav return NULL; 295*e2d15004SDag-Erling Smørgrav 296*e2d15004SDag-Erling Smørgrav event_set(ev, fd, NATIVE_BITS(bits), NATIVE_BITS_CB(cb), arg); 297*e2d15004SDag-Erling Smørgrav if (event_base_set(AS_EVENT_BASE(base), ev) != 0) { 298*e2d15004SDag-Erling Smørgrav free(ev); 299*e2d15004SDag-Erling Smørgrav return NULL; 300*e2d15004SDag-Erling Smørgrav } 301*e2d15004SDag-Erling Smørgrav return AS_UB_EVENT(ev); 302*e2d15004SDag-Erling Smørgrav } 303*e2d15004SDag-Erling Smørgrav 304*e2d15004SDag-Erling Smørgrav struct ub_event* 305*e2d15004SDag-Erling Smørgrav ub_signal_new(struct ub_event_base* base, int fd, 306*e2d15004SDag-Erling Smørgrav void (*cb)(int, short, void*), void* arg) 307*e2d15004SDag-Erling Smørgrav { 308*e2d15004SDag-Erling Smørgrav struct event *ev = (struct event*)calloc(1, sizeof(struct event)); 309*e2d15004SDag-Erling Smørgrav 310*e2d15004SDag-Erling Smørgrav if (!ev) 311*e2d15004SDag-Erling Smørgrav return NULL; 312*e2d15004SDag-Erling Smørgrav 313*e2d15004SDag-Erling Smørgrav signal_set(ev, fd, NATIVE_BITS_CB(cb), arg); 314*e2d15004SDag-Erling Smørgrav if (event_base_set(AS_EVENT_BASE(base), ev) != 0) { 315*e2d15004SDag-Erling Smørgrav free(ev); 316*e2d15004SDag-Erling Smørgrav return NULL; 317*e2d15004SDag-Erling Smørgrav } 318*e2d15004SDag-Erling Smørgrav return AS_UB_EVENT(ev); 319*e2d15004SDag-Erling Smørgrav } 320*e2d15004SDag-Erling Smørgrav 321*e2d15004SDag-Erling Smørgrav struct ub_event* 322*e2d15004SDag-Erling Smørgrav ub_winsock_register_wsaevent(struct ub_event_base* base, void* wsaevent, 323*e2d15004SDag-Erling Smørgrav void (*cb)(int, short, void*), void* arg) 324*e2d15004SDag-Erling Smørgrav { 325*e2d15004SDag-Erling Smørgrav #if defined(USE_MINI_EVENT) && defined(USE_WINSOCK) 326*e2d15004SDag-Erling Smørgrav struct event *ev = (struct event*)calloc(1, sizeof(struct event)); 327*e2d15004SDag-Erling Smørgrav 328*e2d15004SDag-Erling Smørgrav if (!ev) 329*e2d15004SDag-Erling Smørgrav return NULL; 330*e2d15004SDag-Erling Smørgrav 331*e2d15004SDag-Erling Smørgrav if (winsock_register_wsaevent(AS_EVENT_BASE(base), ev, wsaevent, cb, 332*e2d15004SDag-Erling Smørgrav arg)) 333*e2d15004SDag-Erling Smørgrav return AS_UB_EVENT(ev); 334*e2d15004SDag-Erling Smørgrav free(ev); 335*e2d15004SDag-Erling Smørgrav return NULL; 336*e2d15004SDag-Erling Smørgrav #else 337*e2d15004SDag-Erling Smørgrav (void)base; 338*e2d15004SDag-Erling Smørgrav (void)wsaevent; 339*e2d15004SDag-Erling Smørgrav (void)cb; 340*e2d15004SDag-Erling Smørgrav (void)arg; 341*e2d15004SDag-Erling Smørgrav return NULL; 342*e2d15004SDag-Erling Smørgrav #endif 343*e2d15004SDag-Erling Smørgrav } 344*e2d15004SDag-Erling Smørgrav 345*e2d15004SDag-Erling Smørgrav void 346*e2d15004SDag-Erling Smørgrav ub_event_add_bits(struct ub_event* ev, short bits) 347*e2d15004SDag-Erling Smørgrav { 348*e2d15004SDag-Erling Smørgrav AS_EVENT(ev)->ev_events |= NATIVE_BITS(bits); 349*e2d15004SDag-Erling Smørgrav } 350*e2d15004SDag-Erling Smørgrav 351*e2d15004SDag-Erling Smørgrav void 352*e2d15004SDag-Erling Smørgrav ub_event_del_bits(struct ub_event* ev, short bits) 353*e2d15004SDag-Erling Smørgrav { 354*e2d15004SDag-Erling Smørgrav AS_EVENT(ev)->ev_events &= ~NATIVE_BITS(bits); 355*e2d15004SDag-Erling Smørgrav } 356*e2d15004SDag-Erling Smørgrav 357*e2d15004SDag-Erling Smørgrav void 358*e2d15004SDag-Erling Smørgrav ub_event_set_fd(struct ub_event* ev, int fd) 359*e2d15004SDag-Erling Smørgrav { 360*e2d15004SDag-Erling Smørgrav AS_EVENT(ev)->ev_fd = fd; 361*e2d15004SDag-Erling Smørgrav } 362*e2d15004SDag-Erling Smørgrav 363*e2d15004SDag-Erling Smørgrav void 364*e2d15004SDag-Erling Smørgrav ub_event_free(struct ub_event* ev) 365*e2d15004SDag-Erling Smørgrav { 366*e2d15004SDag-Erling Smørgrav if (ev) 367*e2d15004SDag-Erling Smørgrav free(AS_EVENT(ev)); 368*e2d15004SDag-Erling Smørgrav } 369*e2d15004SDag-Erling Smørgrav 370*e2d15004SDag-Erling Smørgrav int 371*e2d15004SDag-Erling Smørgrav ub_event_add(struct ub_event* ev, struct timeval* tv) 372*e2d15004SDag-Erling Smørgrav { 373*e2d15004SDag-Erling Smørgrav return event_add(AS_EVENT(ev), tv); 374*e2d15004SDag-Erling Smørgrav } 375*e2d15004SDag-Erling Smørgrav 376*e2d15004SDag-Erling Smørgrav int 377*e2d15004SDag-Erling Smørgrav ub_event_del(struct ub_event* ev) 378*e2d15004SDag-Erling Smørgrav { 379*e2d15004SDag-Erling Smørgrav return event_del(AS_EVENT(ev)); 380*e2d15004SDag-Erling Smørgrav } 381*e2d15004SDag-Erling Smørgrav 382*e2d15004SDag-Erling Smørgrav int 383*e2d15004SDag-Erling Smørgrav ub_timer_add(struct ub_event* ev, struct ub_event_base* base, 384*e2d15004SDag-Erling Smørgrav void (*cb)(int, short, void*), void* arg, struct timeval* tv) 385*e2d15004SDag-Erling Smørgrav { 386*e2d15004SDag-Erling Smørgrav event_set(AS_EVENT(ev), -1, EV_TIMEOUT, NATIVE_BITS_CB(cb), arg); 387*e2d15004SDag-Erling Smørgrav if (event_base_set(AS_EVENT_BASE(base), AS_EVENT(ev)) != 0) 388*e2d15004SDag-Erling Smørgrav return -1; 389*e2d15004SDag-Erling Smørgrav return evtimer_add(AS_EVENT(ev), tv); 390*e2d15004SDag-Erling Smørgrav } 391*e2d15004SDag-Erling Smørgrav 392*e2d15004SDag-Erling Smørgrav int 393*e2d15004SDag-Erling Smørgrav ub_timer_del(struct ub_event* ev) 394*e2d15004SDag-Erling Smørgrav { 395*e2d15004SDag-Erling Smørgrav return evtimer_del(AS_EVENT(ev)); 396*e2d15004SDag-Erling Smørgrav } 397*e2d15004SDag-Erling Smørgrav 398*e2d15004SDag-Erling Smørgrav int 399*e2d15004SDag-Erling Smørgrav ub_signal_add(struct ub_event* ev, struct timeval* tv) 400*e2d15004SDag-Erling Smørgrav { 401*e2d15004SDag-Erling Smørgrav return signal_add(AS_EVENT(ev), tv); 402*e2d15004SDag-Erling Smørgrav } 403*e2d15004SDag-Erling Smørgrav 404*e2d15004SDag-Erling Smørgrav int 405*e2d15004SDag-Erling Smørgrav ub_signal_del(struct ub_event* ev) 406*e2d15004SDag-Erling Smørgrav { 407*e2d15004SDag-Erling Smørgrav return signal_del(AS_EVENT(ev)); 408*e2d15004SDag-Erling Smørgrav } 409*e2d15004SDag-Erling Smørgrav 410*e2d15004SDag-Erling Smørgrav void 411*e2d15004SDag-Erling Smørgrav ub_winsock_unregister_wsaevent(struct ub_event* ev) 412*e2d15004SDag-Erling Smørgrav { 413*e2d15004SDag-Erling Smørgrav #if defined(USE_MINI_EVENT) && defined(USE_WINSOCK) 414*e2d15004SDag-Erling Smørgrav winsock_unregister_wsaevent(AS_EVENT(ev)); 415*e2d15004SDag-Erling Smørgrav free(AS_EVENT(ev)); 416*e2d15004SDag-Erling Smørgrav #else 417*e2d15004SDag-Erling Smørgrav (void)ev; 418*e2d15004SDag-Erling Smørgrav #endif 419*e2d15004SDag-Erling Smørgrav } 420*e2d15004SDag-Erling Smørgrav 421*e2d15004SDag-Erling Smørgrav void 422*e2d15004SDag-Erling Smørgrav ub_winsock_tcp_wouldblock(struct ub_event* ev, int eventbits) 423*e2d15004SDag-Erling Smørgrav { 424*e2d15004SDag-Erling Smørgrav #if defined(USE_MINI_EVENT) && defined(USE_WINSOCK) 425*e2d15004SDag-Erling Smørgrav winsock_tcp_wouldblock(AS_EVENT(ev), NATIVE_BITS(eventbits)); 426*e2d15004SDag-Erling Smørgrav #else 427*e2d15004SDag-Erling Smørgrav (void)ev; 428*e2d15004SDag-Erling Smørgrav (void)eventbits; 429*e2d15004SDag-Erling Smørgrav #endif 430*e2d15004SDag-Erling Smørgrav } 431*e2d15004SDag-Erling Smørgrav 432*e2d15004SDag-Erling Smørgrav void ub_comm_base_now(struct comm_base* cb) 433*e2d15004SDag-Erling Smørgrav { 434*e2d15004SDag-Erling Smørgrav #ifdef USE_MINI_EVENT 435*e2d15004SDag-Erling Smørgrav /** minievent updates the time when it blocks. */ 436*e2d15004SDag-Erling Smørgrav (void)cb; /* nothing to do */ 437*e2d15004SDag-Erling Smørgrav #else /* !USE_MINI_EVENT */ 438*e2d15004SDag-Erling Smørgrav /** fillup the time values in the event base */ 439*e2d15004SDag-Erling Smørgrav time_t *tt; 440*e2d15004SDag-Erling Smørgrav struct timeval *tv; 441*e2d15004SDag-Erling Smørgrav comm_base_timept(cb, &tt, &tv); 442*e2d15004SDag-Erling Smørgrav if(gettimeofday(tv, NULL) < 0) { 443*e2d15004SDag-Erling Smørgrav log_err("gettimeofday: %s", strerror(errno)); 444*e2d15004SDag-Erling Smørgrav } 445*e2d15004SDag-Erling Smørgrav *tt = tv->tv_sec; 446*e2d15004SDag-Erling Smørgrav #endif /* USE_MINI_EVENT */ 447*e2d15004SDag-Erling Smørgrav } 448*e2d15004SDag-Erling Smørgrav 449