12ee382b6Ssthen /*
2*e21c60efSsthen * util/ub_event.c - directly call libevent (compatibility) functions
32ee382b6Ssthen *
42ee382b6Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved.
52ee382b6Ssthen *
62ee382b6Ssthen * This software is open source.
72ee382b6Ssthen *
82ee382b6Ssthen * Redistribution and use in source and binary forms, with or without
92ee382b6Ssthen * modification, are permitted provided that the following conditions
102ee382b6Ssthen * are met:
112ee382b6Ssthen *
122ee382b6Ssthen * Redistributions of source code must retain the above copyright notice,
132ee382b6Ssthen * this list of conditions and the following disclaimer.
142ee382b6Ssthen *
152ee382b6Ssthen * Redistributions in binary form must reproduce the above copyright notice,
162ee382b6Ssthen * this list of conditions and the following disclaimer in the documentation
172ee382b6Ssthen * and/or other materials provided with the distribution.
182ee382b6Ssthen *
192ee382b6Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may
202ee382b6Ssthen * be used to endorse or promote products derived from this software without
212ee382b6Ssthen * specific prior written permission.
222ee382b6Ssthen *
232ee382b6Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
242ee382b6Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
252ee382b6Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
262ee382b6Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
272ee382b6Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
282ee382b6Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
292ee382b6Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
302ee382b6Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
312ee382b6Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
322ee382b6Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
332ee382b6Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
342ee382b6Ssthen */
352ee382b6Ssthen
362ee382b6Ssthen /**
372ee382b6Ssthen * \file
382ee382b6Ssthen *
392ee382b6Ssthen * This file contains and implementation for the indirection layer for pluggable
402ee382b6Ssthen * events that transparently passes it either directly to libevent, or calls
412ee382b6Ssthen * the libevent compatibility layer functions.
422ee382b6Ssthen */
432ee382b6Ssthen #include "config.h"
442ee382b6Ssthen #include <sys/time.h>
452ee382b6Ssthen #include "util/ub_event.h"
462ee382b6Ssthen #include "util/log.h"
472ee382b6Ssthen #include "util/netevent.h"
482ee382b6Ssthen #include "util/tube.h"
492ee382b6Ssthen
502ee382b6Ssthen /* We define libevent structures here to hide the libevent stuff. */
512ee382b6Ssthen
522ee382b6Ssthen #ifdef USE_MINI_EVENT
532ee382b6Ssthen # ifdef USE_WINSOCK
542ee382b6Ssthen # include "util/winsock_event.h"
552ee382b6Ssthen # else
562ee382b6Ssthen # include "util/mini_event.h"
572ee382b6Ssthen # endif /* USE_WINSOCK */
582ee382b6Ssthen #else /* USE_MINI_EVENT */
592ee382b6Ssthen /* we use libevent */
602ee382b6Ssthen # ifdef HAVE_EVENT_H
612ee382b6Ssthen # include <event.h>
622ee382b6Ssthen # else
632ee382b6Ssthen # include "event2/event.h"
642ee382b6Ssthen # include "event2/event_struct.h"
652ee382b6Ssthen # include "event2/event_compat.h"
662ee382b6Ssthen # endif
672ee382b6Ssthen #endif /* USE_MINI_EVENT */
682ee382b6Ssthen
692ee382b6Ssthen #if UB_EV_TIMEOUT != EV_TIMEOUT || UB_EV_READ != EV_READ || \
702ee382b6Ssthen UB_EV_WRITE != EV_WRITE || UB_EV_SIGNAL != EV_SIGNAL || \
712ee382b6Ssthen UB_EV_PERSIST != EV_PERSIST
722ee382b6Ssthen /* Only necessary for libev */
732ee382b6Ssthen # define NATIVE_BITS(b) ( \
742ee382b6Ssthen (((b) & UB_EV_TIMEOUT) ? EV_TIMEOUT : 0) \
752ee382b6Ssthen | (((b) & UB_EV_READ ) ? EV_READ : 0) \
762ee382b6Ssthen | (((b) & UB_EV_WRITE ) ? EV_WRITE : 0) \
772ee382b6Ssthen | (((b) & UB_EV_SIGNAL ) ? EV_SIGNAL : 0) \
782ee382b6Ssthen | (((b) & UB_EV_PERSIST) ? EV_PERSIST : 0))
792ee382b6Ssthen
802ee382b6Ssthen # define UB_EV_BITS(b) ( \
812ee382b6Ssthen (((b) & EV_TIMEOUT) ? UB_EV_TIMEOUT : 0) \
822ee382b6Ssthen | (((b) & EV_READ ) ? UB_EV_READ : 0) \
832ee382b6Ssthen | (((b) & EV_WRITE ) ? UB_EV_WRITE : 0) \
842ee382b6Ssthen | (((b) & EV_SIGNAL ) ? UB_EV_SIGNAL : 0) \
852ee382b6Ssthen | (((b) & EV_PERSIST) ? UB_EV_PERSIST : 0))
862ee382b6Ssthen
872ee382b6Ssthen # define UB_EV_BITS_CB(C) void my_ ## C (int fd, short bits, void *arg) \
882ee382b6Ssthen { (C)(fd, UB_EV_BITS(bits), arg); }
892ee382b6Ssthen
902ee382b6Ssthen UB_EV_BITS_CB(comm_point_udp_callback);
912ee382b6Ssthen UB_EV_BITS_CB(comm_point_udp_ancil_callback)
UB_EV_BITS_CB(comm_point_tcp_accept_callback)922ee382b6Ssthen UB_EV_BITS_CB(comm_point_tcp_accept_callback)
932ee382b6Ssthen UB_EV_BITS_CB(comm_point_tcp_handle_callback)
942ee382b6Ssthen UB_EV_BITS_CB(comm_timer_callback)
952ee382b6Ssthen UB_EV_BITS_CB(comm_signal_callback)
962ee382b6Ssthen UB_EV_BITS_CB(comm_point_local_handle_callback)
972ee382b6Ssthen UB_EV_BITS_CB(comm_point_raw_handle_callback)
9820237c55Ssthen UB_EV_BITS_CB(comm_point_http_handle_callback)
992ee382b6Ssthen UB_EV_BITS_CB(tube_handle_signal)
1002ee382b6Ssthen UB_EV_BITS_CB(comm_base_handle_slow_accept)
1012ee382b6Ssthen
1022ee382b6Ssthen static void (*NATIVE_BITS_CB(void (*cb)(int, short, void*)))(int, short, void*)
1032ee382b6Ssthen {
1042ee382b6Ssthen if(cb == comm_point_udp_callback)
1052ee382b6Ssthen return my_comm_point_udp_callback;
1062ee382b6Ssthen else if(cb == comm_point_udp_ancil_callback)
1072ee382b6Ssthen return my_comm_point_udp_ancil_callback;
1082ee382b6Ssthen else if(cb == comm_point_tcp_accept_callback)
1092ee382b6Ssthen return my_comm_point_tcp_accept_callback;
1102ee382b6Ssthen else if(cb == comm_point_tcp_handle_callback)
1112ee382b6Ssthen return my_comm_point_tcp_handle_callback;
1122ee382b6Ssthen else if(cb == comm_timer_callback)
1132ee382b6Ssthen return my_comm_timer_callback;
1142ee382b6Ssthen else if(cb == comm_signal_callback)
1152ee382b6Ssthen return my_comm_signal_callback;
1162ee382b6Ssthen else if(cb == comm_point_local_handle_callback)
1172ee382b6Ssthen return my_comm_point_local_handle_callback;
1182ee382b6Ssthen else if(cb == comm_point_raw_handle_callback)
1192ee382b6Ssthen return my_comm_point_raw_handle_callback;
12020237c55Ssthen else if(cb == comm_point_http_handle_callback)
12120237c55Ssthen return my_comm_point_http_handle_callback;
1222ee382b6Ssthen else if(cb == tube_handle_signal)
1232ee382b6Ssthen return my_tube_handle_signal;
1242ee382b6Ssthen else if(cb == comm_base_handle_slow_accept)
1252ee382b6Ssthen return my_comm_base_handle_slow_accept;
12620237c55Ssthen else {
12720237c55Ssthen log_assert(0); /* this NULL callback pointer should not happen,
12820237c55Ssthen we should have the necessary routine listed above */
1292ee382b6Ssthen return NULL;
1302ee382b6Ssthen }
13120237c55Ssthen }
1322ee382b6Ssthen #else
1332ee382b6Ssthen # define NATIVE_BITS(b) (b)
1342ee382b6Ssthen # define NATIVE_BITS_CB(c) (c)
1352ee382b6Ssthen #endif
1362ee382b6Ssthen
1372ee382b6Ssthen #ifndef EVFLAG_AUTO
1382ee382b6Ssthen #define EVFLAG_AUTO 0
1392ee382b6Ssthen #endif
1402ee382b6Ssthen
14177079be7Ssthen #define AS_EVENT_BASE(x) ((struct event_base*)x)
14277079be7Ssthen #define AS_UB_EVENT_BASE(x) ((struct ub_event_base*)x)
14377079be7Ssthen #define AS_EVENT(x) ((struct event*)x)
14477079be7Ssthen #define AS_UB_EVENT(x) ((struct ub_event*)x)
1452ee382b6Ssthen
ub_event_get_version(void)14677079be7Ssthen const char* ub_event_get_version(void)
1472ee382b6Ssthen {
1482ee382b6Ssthen return event_get_version();
1492ee382b6Ssthen }
1502ee382b6Ssthen
151a3167c07Ssthen #if (defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && defined(EV_FEATURE_BACKENDS)
ub_ev_backend2str(int b)1522ee382b6Ssthen static const char* ub_ev_backend2str(int b)
1532ee382b6Ssthen {
1542ee382b6Ssthen switch(b) {
1552ee382b6Ssthen case EVBACKEND_SELECT: return "select";
1562ee382b6Ssthen case EVBACKEND_POLL: return "poll";
1572ee382b6Ssthen case EVBACKEND_EPOLL: return "epoll";
1582ee382b6Ssthen case EVBACKEND_KQUEUE: return "kqueue";
1592ee382b6Ssthen case EVBACKEND_DEVPOLL: return "devpoll";
1602ee382b6Ssthen case EVBACKEND_PORT: return "evport";
1612ee382b6Ssthen }
1622ee382b6Ssthen return "unknown";
1632ee382b6Ssthen }
1642ee382b6Ssthen #endif
1652ee382b6Ssthen
1662ee382b6Ssthen void
ub_get_event_sys(struct ub_event_base * base,const char ** n,const char ** s,const char ** m)1672ee382b6Ssthen ub_get_event_sys(struct ub_event_base* base, const char** n, const char** s,
1682ee382b6Ssthen const char** m)
1692ee382b6Ssthen {
1702ee382b6Ssthen #ifdef USE_WINSOCK
1712ee382b6Ssthen (void)base;
1722ee382b6Ssthen *n = "event";
1732ee382b6Ssthen *s = "winsock";
1742ee382b6Ssthen *m = "WSAWaitForMultipleEvents";
1752ee382b6Ssthen #elif defined(USE_MINI_EVENT)
1762ee382b6Ssthen (void)base;
1772ee382b6Ssthen *n = "mini-event";
1782ee382b6Ssthen *s = "internal";
1792ee382b6Ssthen *m = "select";
1802ee382b6Ssthen #else
1812ee382b6Ssthen struct event_base* b = AS_EVENT_BASE(base);
1822ee382b6Ssthen *s = event_get_version();
1832ee382b6Ssthen # if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
1842ee382b6Ssthen *n = "libev";
1852ee382b6Ssthen if (!b)
1862ee382b6Ssthen b = (struct event_base*)ev_default_loop(EVFLAG_AUTO);
187a3167c07Ssthen # ifdef EV_FEATURE_BACKENDS
1882ee382b6Ssthen *m = ub_ev_backend2str(ev_backend((struct ev_loop*)b));
1892ee382b6Ssthen # else
1902ee382b6Ssthen *m = "not obtainable";
1912ee382b6Ssthen # endif
1922ee382b6Ssthen # elif defined(HAVE_EVENT_BASE_GET_METHOD)
1932ee382b6Ssthen *n = "libevent";
1942ee382b6Ssthen if (!b)
1952ee382b6Ssthen b = event_base_new();
1962ee382b6Ssthen *m = event_base_get_method(b);
1972ee382b6Ssthen # else
1982ee382b6Ssthen *n = "unknown";
1992ee382b6Ssthen *m = "not obtainable";
2002ee382b6Ssthen (void)b;
2012ee382b6Ssthen # endif
2022ee382b6Ssthen # ifdef HAVE_EVENT_BASE_FREE
2032ee382b6Ssthen if (b && b != AS_EVENT_BASE(base))
2042ee382b6Ssthen event_base_free(b);
2052ee382b6Ssthen # endif
2062ee382b6Ssthen #endif
2072ee382b6Ssthen }
2082ee382b6Ssthen
2092ee382b6Ssthen struct ub_event_base*
ub_default_event_base(int sigs,time_t * time_secs,struct timeval * time_tv)2102ee382b6Ssthen ub_default_event_base(int sigs, time_t* time_secs, struct timeval* time_tv)
2112ee382b6Ssthen {
2122ee382b6Ssthen void* base;
2132ee382b6Ssthen
2142ee382b6Ssthen (void)base;
2152ee382b6Ssthen #ifdef USE_MINI_EVENT
2162ee382b6Ssthen (void)sigs;
2172ee382b6Ssthen /* use mini event time-sharing feature */
2182ee382b6Ssthen base = event_init(time_secs, time_tv);
2192ee382b6Ssthen #else
2202ee382b6Ssthen (void)time_secs;
2212ee382b6Ssthen (void)time_tv;
2222ee382b6Ssthen # if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
2232ee382b6Ssthen /* libev */
2242ee382b6Ssthen if(sigs)
2252ee382b6Ssthen base = ev_default_loop(EVFLAG_AUTO);
2262ee382b6Ssthen else
2272ee382b6Ssthen base = ev_loop_new(EVFLAG_AUTO);
2282ee382b6Ssthen # else
2292ee382b6Ssthen (void)sigs;
2302ee382b6Ssthen # ifdef HAVE_EVENT_BASE_NEW
2312ee382b6Ssthen base = event_base_new();
2322ee382b6Ssthen # else
2332ee382b6Ssthen base = event_init();
2342ee382b6Ssthen # endif
2352ee382b6Ssthen # endif
2362ee382b6Ssthen #endif
2372ee382b6Ssthen return (struct ub_event_base*)base;
2382ee382b6Ssthen }
2392ee382b6Ssthen
2402ee382b6Ssthen struct ub_event_base *
ub_libevent_event_base(struct event_base * libevent_base)2412ee382b6Ssthen ub_libevent_event_base(struct event_base* libevent_base)
2422ee382b6Ssthen {
2432ee382b6Ssthen #ifdef USE_MINI_EVENT
2442ee382b6Ssthen (void)libevent_base;
2452ee382b6Ssthen return NULL;
2462ee382b6Ssthen #else
2472ee382b6Ssthen return AS_UB_EVENT_BASE(libevent_base);
2482ee382b6Ssthen #endif
2492ee382b6Ssthen }
2502ee382b6Ssthen
2512ee382b6Ssthen struct event_base *
ub_libevent_get_event_base(struct ub_event_base * base)2522ee382b6Ssthen ub_libevent_get_event_base(struct ub_event_base* base)
2532ee382b6Ssthen {
2542ee382b6Ssthen #ifdef USE_MINI_EVENT
2552ee382b6Ssthen (void)base;
2562ee382b6Ssthen return NULL;
2572ee382b6Ssthen #else
2582ee382b6Ssthen return AS_EVENT_BASE(base);
2592ee382b6Ssthen #endif
2602ee382b6Ssthen }
2612ee382b6Ssthen
2622ee382b6Ssthen void
ub_event_base_free(struct ub_event_base * base)2632ee382b6Ssthen ub_event_base_free(struct ub_event_base* base)
2642ee382b6Ssthen {
2652ee382b6Ssthen #ifdef USE_MINI_EVENT
2662ee382b6Ssthen event_base_free(AS_EVENT_BASE(base));
2672ee382b6Ssthen #elif defined(HAVE_EVENT_BASE_FREE) && defined(HAVE_EVENT_BASE_ONCE)
2682ee382b6Ssthen /* only libevent 1.2+ has it, but in 1.2 it is broken -
2692ee382b6Ssthen assertion fails on signal handling ev that is not deleted
2702ee382b6Ssthen in libevent 1.3c (event_base_once appears) this is fixed. */
2712ee382b6Ssthen event_base_free(AS_EVENT_BASE(base));
2722ee382b6Ssthen #else
2732ee382b6Ssthen (void)base;
2742ee382b6Ssthen #endif /* HAVE_EVENT_BASE_FREE and HAVE_EVENT_BASE_ONCE */
2752ee382b6Ssthen }
2762ee382b6Ssthen
2772ee382b6Ssthen int
ub_event_base_dispatch(struct ub_event_base * base)2782ee382b6Ssthen ub_event_base_dispatch(struct ub_event_base* base)
2792ee382b6Ssthen {
2802ee382b6Ssthen return event_base_dispatch(AS_EVENT_BASE(base));
2812ee382b6Ssthen }
2822ee382b6Ssthen
2832ee382b6Ssthen int
ub_event_base_loopexit(struct ub_event_base * base)2842ee382b6Ssthen ub_event_base_loopexit(struct ub_event_base* base)
2852ee382b6Ssthen {
2862ee382b6Ssthen return event_base_loopexit(AS_EVENT_BASE(base), NULL);
2872ee382b6Ssthen }
2882ee382b6Ssthen
2892ee382b6Ssthen struct ub_event*
ub_event_new(struct ub_event_base * base,int fd,short bits,void (* cb)(int,short,void *),void * arg)2902ee382b6Ssthen ub_event_new(struct ub_event_base* base, int fd, short bits,
2912ee382b6Ssthen void (*cb)(int, short, void*), void* arg)
2922ee382b6Ssthen {
2932ee382b6Ssthen struct event *ev = (struct event*)calloc(1, sizeof(struct event));
2942ee382b6Ssthen
2952ee382b6Ssthen if (!ev)
2962ee382b6Ssthen return NULL;
2972ee382b6Ssthen
298550cf4a9Ssthen #ifndef HAVE_EVENT_ASSIGN
2992ee382b6Ssthen event_set(ev, fd, NATIVE_BITS(bits), NATIVE_BITS_CB(cb), arg);
3002ee382b6Ssthen if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
3012ee382b6Ssthen free(ev);
3022ee382b6Ssthen return NULL;
3032ee382b6Ssthen }
304550cf4a9Ssthen #else
305550cf4a9Ssthen if (event_assign(ev, AS_EVENT_BASE(base), fd, bits, cb, arg) != 0) {
306550cf4a9Ssthen free(ev);
307550cf4a9Ssthen return NULL;
308550cf4a9Ssthen }
309550cf4a9Ssthen #endif
3102ee382b6Ssthen return AS_UB_EVENT(ev);
3112ee382b6Ssthen }
3122ee382b6Ssthen
3132ee382b6Ssthen struct ub_event*
ub_signal_new(struct ub_event_base * base,int fd,void (* cb)(int,short,void *),void * arg)3142ee382b6Ssthen ub_signal_new(struct ub_event_base* base, int fd,
3152ee382b6Ssthen void (*cb)(int, short, void*), void* arg)
3162ee382b6Ssthen {
3172ee382b6Ssthen struct event *ev = (struct event*)calloc(1, sizeof(struct event));
3182ee382b6Ssthen
3192ee382b6Ssthen if (!ev)
3202ee382b6Ssthen return NULL;
3212ee382b6Ssthen
322550cf4a9Ssthen #if !HAVE_DECL_EVSIGNAL_ASSIGN
3232ee382b6Ssthen signal_set(ev, fd, NATIVE_BITS_CB(cb), arg);
3242ee382b6Ssthen if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
3252ee382b6Ssthen free(ev);
3262ee382b6Ssthen return NULL;
3272ee382b6Ssthen }
328550cf4a9Ssthen #else
329550cf4a9Ssthen if (evsignal_assign(ev, AS_EVENT_BASE(base), fd, cb, arg) != 0) {
330550cf4a9Ssthen free(ev);
331550cf4a9Ssthen return NULL;
332550cf4a9Ssthen }
333550cf4a9Ssthen #endif
3342ee382b6Ssthen return AS_UB_EVENT(ev);
3352ee382b6Ssthen }
3362ee382b6Ssthen
3372ee382b6Ssthen struct ub_event*
ub_winsock_register_wsaevent(struct ub_event_base * base,void * wsaevent,void (* cb)(int,short,void *),void * arg)3382ee382b6Ssthen ub_winsock_register_wsaevent(struct ub_event_base* base, void* wsaevent,
3392ee382b6Ssthen void (*cb)(int, short, void*), void* arg)
3402ee382b6Ssthen {
3412ee382b6Ssthen #if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
3422ee382b6Ssthen struct event *ev = (struct event*)calloc(1, sizeof(struct event));
3432ee382b6Ssthen
3442ee382b6Ssthen if (!ev)
3452ee382b6Ssthen return NULL;
3462ee382b6Ssthen
3472ee382b6Ssthen if (winsock_register_wsaevent(AS_EVENT_BASE(base), ev, wsaevent, cb,
3482ee382b6Ssthen arg))
3492ee382b6Ssthen return AS_UB_EVENT(ev);
3502ee382b6Ssthen free(ev);
3512ee382b6Ssthen return NULL;
3522ee382b6Ssthen #else
3532ee382b6Ssthen (void)base;
3542ee382b6Ssthen (void)wsaevent;
3552ee382b6Ssthen (void)cb;
3562ee382b6Ssthen (void)arg;
3572ee382b6Ssthen return NULL;
3582ee382b6Ssthen #endif
3592ee382b6Ssthen }
3602ee382b6Ssthen
3612ee382b6Ssthen void
ub_event_add_bits(struct ub_event * ev,short bits)3622ee382b6Ssthen ub_event_add_bits(struct ub_event* ev, short bits)
3632ee382b6Ssthen {
3642ee382b6Ssthen AS_EVENT(ev)->ev_events |= NATIVE_BITS(bits);
3652ee382b6Ssthen }
3662ee382b6Ssthen
3672ee382b6Ssthen void
ub_event_del_bits(struct ub_event * ev,short bits)3682ee382b6Ssthen ub_event_del_bits(struct ub_event* ev, short bits)
3692ee382b6Ssthen {
3702ee382b6Ssthen AS_EVENT(ev)->ev_events &= ~NATIVE_BITS(bits);
3712ee382b6Ssthen }
3722ee382b6Ssthen
3732ee382b6Ssthen void
ub_event_set_fd(struct ub_event * ev,int fd)3742ee382b6Ssthen ub_event_set_fd(struct ub_event* ev, int fd)
3752ee382b6Ssthen {
3762ee382b6Ssthen AS_EVENT(ev)->ev_fd = fd;
3772ee382b6Ssthen }
3782ee382b6Ssthen
3792ee382b6Ssthen void
ub_event_free(struct ub_event * ev)3802ee382b6Ssthen ub_event_free(struct ub_event* ev)
3812ee382b6Ssthen {
3822ee382b6Ssthen if (ev)
3832ee382b6Ssthen free(AS_EVENT(ev));
3842ee382b6Ssthen }
3852ee382b6Ssthen
3862ee382b6Ssthen int
ub_event_add(struct ub_event * ev,struct timeval * tv)3872ee382b6Ssthen ub_event_add(struct ub_event* ev, struct timeval* tv)
3882ee382b6Ssthen {
3892ee382b6Ssthen return event_add(AS_EVENT(ev), tv);
3902ee382b6Ssthen }
3912ee382b6Ssthen
3922ee382b6Ssthen int
ub_event_del(struct ub_event * ev)3932ee382b6Ssthen ub_event_del(struct ub_event* ev)
3942ee382b6Ssthen {
3952ee382b6Ssthen return event_del(AS_EVENT(ev));
3962ee382b6Ssthen }
3972ee382b6Ssthen
3982ee382b6Ssthen int
ub_timer_add(struct ub_event * ev,struct ub_event_base * base,void (* cb)(int,short,void *),void * arg,struct timeval * tv)3992ee382b6Ssthen ub_timer_add(struct ub_event* ev, struct ub_event_base* base,
4002ee382b6Ssthen void (*cb)(int, short, void*), void* arg, struct timeval* tv)
4012ee382b6Ssthen {
4022ee382b6Ssthen event_set(AS_EVENT(ev), -1, EV_TIMEOUT, NATIVE_BITS_CB(cb), arg);
4032ee382b6Ssthen if (event_base_set(AS_EVENT_BASE(base), AS_EVENT(ev)) != 0)
4042ee382b6Ssthen return -1;
4052ee382b6Ssthen return evtimer_add(AS_EVENT(ev), tv);
4062ee382b6Ssthen }
4072ee382b6Ssthen
4082ee382b6Ssthen int
ub_timer_del(struct ub_event * ev)4092ee382b6Ssthen ub_timer_del(struct ub_event* ev)
4102ee382b6Ssthen {
4112ee382b6Ssthen return evtimer_del(AS_EVENT(ev));
4122ee382b6Ssthen }
4132ee382b6Ssthen
4142ee382b6Ssthen int
ub_signal_add(struct ub_event * ev,struct timeval * tv)4152ee382b6Ssthen ub_signal_add(struct ub_event* ev, struct timeval* tv)
4162ee382b6Ssthen {
4172ee382b6Ssthen return signal_add(AS_EVENT(ev), tv);
4182ee382b6Ssthen }
4192ee382b6Ssthen
4202ee382b6Ssthen int
ub_signal_del(struct ub_event * ev)4212ee382b6Ssthen ub_signal_del(struct ub_event* ev)
4222ee382b6Ssthen {
4232ee382b6Ssthen return signal_del(AS_EVENT(ev));
4242ee382b6Ssthen }
4252ee382b6Ssthen
4262ee382b6Ssthen void
ub_winsock_unregister_wsaevent(struct ub_event * ev)4272ee382b6Ssthen ub_winsock_unregister_wsaevent(struct ub_event* ev)
4282ee382b6Ssthen {
4292ee382b6Ssthen #if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
4302ee382b6Ssthen winsock_unregister_wsaevent(AS_EVENT(ev));
4312ee382b6Ssthen free(AS_EVENT(ev));
4322ee382b6Ssthen #else
4332ee382b6Ssthen (void)ev;
4342ee382b6Ssthen #endif
4352ee382b6Ssthen }
4362ee382b6Ssthen
4372ee382b6Ssthen void
ub_winsock_tcp_wouldblock(struct ub_event * ev,int eventbits)4382ee382b6Ssthen ub_winsock_tcp_wouldblock(struct ub_event* ev, int eventbits)
4392ee382b6Ssthen {
4402ee382b6Ssthen #if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
4412ee382b6Ssthen winsock_tcp_wouldblock(AS_EVENT(ev), NATIVE_BITS(eventbits));
4422ee382b6Ssthen #else
4432ee382b6Ssthen (void)ev;
4442ee382b6Ssthen (void)eventbits;
4452ee382b6Ssthen #endif
4462ee382b6Ssthen }
4472ee382b6Ssthen
ub_comm_base_now(struct comm_base * cb)4482ee382b6Ssthen void ub_comm_base_now(struct comm_base* cb)
4492ee382b6Ssthen {
4502ee382b6Ssthen #ifdef USE_MINI_EVENT
4512ee382b6Ssthen /** minievent updates the time when it blocks. */
4522ee382b6Ssthen (void)cb; /* nothing to do */
4532ee382b6Ssthen #else /* !USE_MINI_EVENT */
4542ee382b6Ssthen /** fillup the time values in the event base */
4552ee382b6Ssthen time_t *tt;
4562ee382b6Ssthen struct timeval *tv;
4572ee382b6Ssthen comm_base_timept(cb, &tt, &tv);
4582ee382b6Ssthen if(gettimeofday(tv, NULL) < 0) {
4592ee382b6Ssthen log_err("gettimeofday: %s", strerror(errno));
4602ee382b6Ssthen }
461ebf5bb73Ssthen #ifndef S_SPLINT_S
4622ee382b6Ssthen *tt = tv->tv_sec;
463ebf5bb73Ssthen #endif
4642ee382b6Ssthen #endif /* USE_MINI_EVENT */
4652ee382b6Ssthen }
4662ee382b6Ssthen
467