xref: /openbsd-src/usr.sbin/unbound/util/ub_event.c (revision e21c60efe88ccf825a55e871fba3e7017d017ae8)
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