User defined pluggable event mechanism (for review)

git-svn-id: file:///svn/unbound/branches/ub_event@3647 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Willem Toorop 2016-03-07 14:10:06 +00:00
parent 4f1625afb7
commit bcfbe0d9c4
23 changed files with 5560 additions and 6728 deletions

View File

@ -108,11 +108,12 @@ util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
util/rtt.c util/storage/dnstree.c util/storage/lookup3.c \
util/storage/lruhash.c util/storage/slabhash.c util/timehist.c util/tube.c \
util/winsock_event.c validator/autotrust.c validator/val_anchor.c \
validator/validator.c validator/val_kcache.c validator/val_kentry.c \
validator/val_neg.c validator/val_nsec3.c validator/val_nsec.c \
validator/val_secalgo.c validator/val_sigcrypt.c \
validator/val_utils.c dns64/dns64.c $(CHECKLOCK_SRC) $(DNSTAP_SRC)
util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
validator/autotrust.c validator/val_anchor.c validator/validator.c \
validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \
validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c $(CHECKLOCK_SRC) \
$(DNSTAP_SRC)
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
@ -124,8 +125,9 @@ slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo \
$(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
# set to $COMMON_OBJ or to "" if --enableallsymbols
COMMON_OBJ_ALL_SYMBOLS=@COMMON_OBJ_ALL_SYMBOLS@
COMPAT_SRC=compat/ctime_r.c compat/fake-rfc2553.c compat/gmtime_r.c \
@ -177,7 +179,8 @@ daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
testcode/replay.c testcode/fake_event.c
TESTBOUND_OBJ=testbound.lo replay.lo fake_event.lo
TESTBOUND_OBJ_LINK=$(TESTBOUND_OBJ) testpkts.lo worker.lo acl_list.lo \
daemon.lo stats.lo $(COMMON_OBJ_WITHOUT_NETCALL) $(SLDNS_OBJ) $(COMPAT_OBJ)
daemon.lo stats.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \
$(COMPAT_OBJ)
LOCKVERIFY_SRC=testcode/lock_verify.c
LOCKVERIFY_OBJ=lock_verify.lo
LOCKVERIFY_OBJ_LINK=$(LOCKVERIFY_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
@ -209,8 +212,8 @@ DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \
libunbound/libworker.c
LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo
LIBUNBOUND_OBJ_LINK=$(LIBUNBOUND_OBJ) $(COMMON_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ)
LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo
LIBUNBOUND_OBJ_LINK=$(LIBUNBOUND_OBJ) $(COMMON_OBJ_WITHOUT_UB_EVENT) $(SLDNS_OBJ) $(COMPAT_OBJ)
# win apps or "" if not on windows
WINAPPS=@WINAPPS@
@ -596,7 +599,6 @@ depend:
rm -f $(DEPEND_TMP) $(DEPEND_TMP2)
# Dependencies
as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
$(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/msgreply.h \
@ -614,6 +616,7 @@ rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/c
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h
as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/storage/lookup3.h $(srcdir)/sldns/sbuffer.h
@ -773,12 +776,12 @@ mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/
module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/util/log.h \
$(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/util/ub_event.h \
$(srcdir)/util/log.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
$(srcdir)/dnstap/dnstap.h
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
@ -809,6 +812,14 @@ tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/u
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h \
$(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h
autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/validator/autotrust.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
@ -822,8 +833,8 @@ autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/val
val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/autotrust.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/as112.h
$(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/as112.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/validator/validator.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
@ -880,7 +891,7 @@ val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/val
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h \
$(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h
dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
@ -994,7 +1005,7 @@ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
$(srcdir)/util/ub_event.h
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
@ -1020,7 +1031,7 @@ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/test
$(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
$(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
@ -1121,9 +1132,10 @@ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbou
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
$(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/services/localzone.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/sldns/sbuffer.h
$(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \
$(srcdir)/services/localzone.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/sldns/sbuffer.h
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \

2704
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

View File

@ -467,7 +467,8 @@
/* if lex has yylex_destroy */
#undef LEX_HAS_YYLEX_DESTROY
/* Define to the sub-directory where libtool stores uninstalled libraries. */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to the maximum message length to pass to syslog. */

2104
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -840,11 +840,11 @@ case "$enable_ecdsa" in
;;
esac
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) libevent-based libunbound API installed to unbound-event.h]))
use_unbound_event="no"
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
case "$enable_event_api" in
yes)
use_unbound_event="yes"
AC_SUBST(UNBOUND_EVENT_INSTALL, [unbound-event-install])
AC_SUBST(UNBOUND_EVENT_UNINSTALL, [unbound-event-uninstall])
;;
*)
;;
@ -930,10 +930,6 @@ large outgoing port ranges. ])
if test -n "$BAK_LDFLAGS_SET"; then
LDFLAGS="$BAK_LDFLAGS"
fi
if test "$use_unbound_event" = "yes"; then
AC_SUBST(UNBOUND_EVENT_INSTALL, [unbound-event-install])
AC_SUBST(UNBOUND_EVENT_UNINSTALL, [unbound-event-uninstall])
fi
else
AC_DEFINE(USE_MINI_EVENT, 1, [Define if you want to use internal select based events])
fi

View File

@ -45,9 +45,6 @@
#include "util/locks.h"
#include "util/alloc.h"
#include "services/modstack.h"
#ifdef UB_ON_WINDOWS
# include "util/winsock_event.h"
#endif
struct config_file;
struct worker;
struct listen_port;

View File

@ -57,6 +57,7 @@
#include "util/data/msgreply.h"
#include "util/module.h"
#include "util/net_help.h"
#include "util/ub_event.h"
#include <signal.h>
#include <fcntl.h>
#include <openssl/crypto.h>
@ -77,22 +78,6 @@
#include <login_cap.h>
#endif
#ifdef USE_MINI_EVENT
# ifdef USE_WINSOCK
# include "util/winsock_event.h"
# else
# include "util/mini_event.h"
# endif
#else
# ifdef HAVE_EVENT_H
# include <event.h>
# else
# include "event2/event.h"
# include "event2/event_struct.h"
# include "event2/event_compat.h"
# endif
#endif
#ifdef UB_ON_WINDOWS
# include "winrc/win_svc.h"
#endif
@ -122,39 +107,6 @@ static const char* ev_backend2str(int b)
}
#endif
/** get the event system in use */
static void get_event_sys(const char** n, const char** s, const char** m)
{
#ifdef USE_WINSOCK
*n = "event";
*s = "winsock";
*m = "WSAWaitForMultipleEvents";
#elif defined(USE_MINI_EVENT)
*n = "mini-event";
*s = "internal";
*m = "select";
#else
struct event_base* b;
*s = event_get_version();
# ifdef HAVE_EVENT_BASE_GET_METHOD
*n = "libevent";
b = event_base_new();
*m = event_base_get_method(b);
# elif defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
*n = "libev";
b = (struct event_base*)ev_default_loop(EVFLAG_AUTO);
*m = ev_backend2str(ev_backend((struct ev_loop*)b));
# else
*n = "unknown";
*m = "not obtainable";
b = NULL;
# endif
# ifdef HAVE_EVENT_BASE_FREE
event_base_free(b);
# endif
#endif
}
/** print usage. */
static void usage()
{
@ -173,7 +125,7 @@ static void usage()
printf(" service - used to start from services control panel\n");
#endif
printf("Version %s\n", PACKAGE_VERSION);
get_event_sys(&evnm, &evsys, &evmethod);
ub_get_event_sys(NULL, &evnm, &evsys, &evmethod);
printf("linked libs: %s %s (it uses %s), %s\n",
evnm, evsys, evmethod,
#ifdef HAVE_SSL
@ -230,7 +182,7 @@ checkrlimits(struct config_file* cfg)
struct rlimit rlim;
if(total > 1024 &&
strncmp(event_get_version(), "mini-event", 10) == 0) {
strncmp(ub_event_get_version(), "mini-event", 10) == 0) {
log_warn("too many file descriptors requested. The builtin"
"mini-event cannot handle more than 1024. Config "
"for less fds or compile with libevent");
@ -244,7 +196,7 @@ checkrlimits(struct config_file* cfg)
total = 1024;
}
if(perthread > 64 &&
strncmp(event_get_version(), "winsock-event", 13) == 0) {
strncmp(ub_event_get_version(), "winsock-event", 13) == 0) {
log_err("too many file descriptors requested. The winsock"
" event handler cannot handle more than 64 per "
" thread. Config for less fds");

View File

@ -49,7 +49,7 @@
struct libworker;
struct tube;
struct sldns_buffer;
struct event_base;
struct ub_event_base;
/**
* The context structure
@ -114,7 +114,7 @@ struct ub_ctx {
struct ub_randstate* seed_rnd;
/** event base for event oriented interface */
struct event_base* event_base;
struct ub_event_base* event_base;
/** libworker for event based interface */
struct libworker* event_worker;

View File

@ -57,6 +57,7 @@
#include "util/random.h"
#include "util/net_help.h"
#include "util/tube.h"
#include "util/ub_event.h"
#include "services/modstack.h"
#include "services/localzone.h"
#include "services/cache/infra.h"
@ -169,6 +170,20 @@ ub_ctx_create(void)
return ctx;
}
struct ub_ctx*
ub_ctx_create_ub_event(struct ub_event_base* ueb)
{
struct ub_ctx* ctx = ub_ctx_create_nopipe();
if(!ctx)
return NULL;
/* no pipes, but we have the locks to make sure everything works */
ctx->created_bg = 0;
ctx->dothread = 1; /* the processing is in the same process,
makes ub_cancel and ub_ctx_delete do the right thing */
ctx->event_base = ueb;
return ctx;
}
struct ub_ctx*
ub_ctx_create_event(struct event_base* eb)
{
@ -179,7 +194,11 @@ ub_ctx_create_event(struct event_base* eb)
ctx->created_bg = 0;
ctx->dothread = 1; /* the processing is in the same process,
makes ub_cancel and ub_ctx_delete do the right thing */
ctx->event_base = eb;
ctx->event_base = ub_libevent_event_base(eb);
if (!ctx->event_base) {
ub_ctx_delete(ctx);
return NULL;
}
return ctx;
}
@ -1323,10 +1342,12 @@ const char* ub_version(void)
int
ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) {
struct ub_event_base* new_base;
if (!ctx || !ctx->event_base || !base) {
return UB_INITFAIL;
}
if (ctx->event_base == base) {
if (ub_libevent_get_event_base(ctx->event_base) == base) {
/* already set */
return UB_NOERROR;
}
@ -1335,9 +1356,11 @@ ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) {
/* destroy the current worker - safe to pass in NULL */
libworker_delete_event(ctx->event_worker);
ctx->event_worker = NULL;
ctx->event_base = base;
new_base = ub_libevent_event_base(base);
if (new_base)
ctx->event_base = new_base;
ctx->created_bg = 0;
ctx->dothread = 1;
lock_basic_unlock(&ctx->cfglock);
return UB_NOERROR;
return new_base ? UB_NOERROR : UB_INITFAIL;
}

View File

@ -119,7 +119,7 @@ libworker_delete_event(struct libworker* w)
/** setup fresh libworker struct */
static struct libworker*
libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb)
libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
{
unsigned int seed;
struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
@ -258,7 +258,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb)
}
struct libworker* libworker_create_event(struct ub_ctx* ctx,
struct event_base* eb)
struct ub_event_base* eb)
{
return libworker_setup(ctx, 0, eb);
}

View File

@ -58,7 +58,7 @@ struct comm_reply;
struct regional;
struct tube;
struct sldns_buffer;
struct event_base;
struct ub_event_base;
/**
* The library-worker status structure
@ -115,7 +115,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q);
* @return new worker or NULL.
*/
struct libworker* libworker_create_event(struct ub_ctx* ctx,
struct event_base* eb);
struct ub_event_base* eb);
/**
* Attach context_query to mesh for callback in event-driven setup.

View File

@ -6,6 +6,7 @@ ub_ctx_async
ub_ctx_config
ub_ctx_create
ub_ctx_create_event
ub_ctx_create_ub_event
ub_ctx_data_add
ub_ctx_data_remove
ub_ctx_debuglevel

View File

@ -36,20 +36,21 @@
/**
* \file
*
* This file contains the unbound interface for use with libevent.
* You have to use the same libevent that unbound was compiled with,
* otherwise it wouldn't work, the event and event_base structures would
* be different. If unbound is compiled without libevent support then
* this header file is not supposed to be installed on the system.
* This file contains the unbound interface for use with user defined
* pluggable event bases.
*
* Use ub_ctx_create_event_base() to create an unbound context that uses
* the event base that you have made. Then, use the ub_resolve_event call
* to add DNS resolve queries to the context. Those then run when you
* call event_dispatch() on your event_base, and when they are done you
* get a function callback.
* Use ub_ctx_create_event_ub_base() to create an unbound context that uses
* the user provided event base API. Then, use the ub_resolve_event call
* to add DNS resolve queries to the context. Those then run whith the
* provided event_base, and when they are done you get a function callback.
*
* This method does not fork another process or create a thread, the effort
* is done by the unbound state machines that are connected to the event_base.
* is done by the unbound state machines that are connected to the event base.
*
* It is also possible to provide a libevent based event base by using
* ub_ctx_create_event_base(). But you have to use the same libevent that
* unbound was compiled with, otherwise it wouldn't work, the event and
* event_base structures would be different.
*/
#ifndef _UB_UNBOUND_EVENT_H
#define _UB_UNBOUND_EVENT_H
@ -62,12 +63,133 @@ struct ub_ctx;
struct ub_result;
struct event_base;
/** event timeout */
#define UB_EV_TIMEOUT 0x01
/** event fd readable */
#define UB_EV_READ 0x02
/** event fd writable */
#define UB_EV_WRITE 0x04
/** event signal */
#define UB_EV_SIGNAL 0x08
/** event must persist */
#define UB_EV_PERSIST 0x10
/** magic number to identify this version of the pluggable event api */
#define UB_EVENT_MAGIC 0x44d74d78
struct ub_event;
struct ub_event_base;
struct timeval;
/**
* The Virtual Method Table for and ub_event_base "object"
*/
struct ub_event_base_vmt {
/** Destructor for the ub_event_base object,
* (not called by libunbound) */
void (*free)(struct ub_event_base*);
/** Run the event loop
* (not called by libunbound when using ub_resolve_event) */
int (*dispatch)(struct ub_event_base*);
/** Exit the given event loop */
int (*loopexit)(struct ub_event_base*, struct timeval*);
/** Instantiate a new ub_event associated with this event base */
struct ub_event* (*new_event)(struct ub_event_base*,
int fd, short bits, void (*cb)(int, short, void*), void* arg);
/** Instantiate a new signal associated with this event base,
* (not called by libunbound) */
struct ub_event* (*new_signal)(struct ub_event_base*, int fd,
void (*cb)(int, short, void*), void* arg);
/** Create a new ub_event associated with the given wsaevent,
* (not called by libunbound) */
struct ub_event* (*winsock_register_wsaevent)(struct ub_event_base*,
void* wsaevent, void (*cb)(int, short, void*), void* arg);
};
/**
* A user defined pluggable event base is registered by providing a
* ub_event_base "object" with the ub_ctx_create_ub_event() function.
* The magic number must be correct and the Virtual Method Table must be
* fully equipped providing the event base API to be used by libunbound.
*/
struct ub_event_base {
/** magic must be UB_EVENT_MAGIC (0x44d74d78) */
unsigned long magic;
/** Virtual Method Table for ub_event_base */
struct ub_event_base_vmt* vmt;
};
/**
* The Virtual Method Table for and ub_event "object"
*/
struct ub_event_vmt {
/** Add event bits for this event to fire on */
void (*add_bits)(struct ub_event*, short);
/** Configure the event so it will not longer fire on given bits */
void (*del_bits)(struct ub_event*, short);
/** Change or set the file descriptor on the event */
void (*set_fd)(struct ub_event*, int);
/** Destructor for the ub_event object */
void (*free)(struct ub_event*);
/** Activate the event. The given timeval is an timeout value. */
int (*add)(struct ub_event*, struct timeval*);
/** Deactivate the event */
int (*del)(struct ub_event*);
/** Reconfigure and activate a timeout event */
int (*add_timer)(struct ub_event*, struct ub_event_base*,
void (*cb)(int, short, void*), void* arg, struct timeval*);
/** Deactivate the timeout event */
int (*del_timer)(struct ub_event*);
/** Activate a signal event (not called by libunbound). */
int (*add_signal)(struct ub_event*, struct timeval*);
/** Deactivate a signal event (not called by libunbound). */
int (*del_signal)(struct ub_event*);
/** Destructor for a ub_event associated with a wsaevent,
* (not called by libunbound)
*/
void (*winsock_unregister_wsaevent)(struct ub_event* ev);
/** Libunbound will signal the eventloop when a TCP windows socket
* will block on next read or write (given by the eventbits), to work
* around edge trigger event behaviour of select on windows with TCP.
*/
void (*winsock_tcp_wouldblock)(struct ub_event*, int eventbit);
};
/**
* An "object" comprising a user defined pluggable event.
* The magic number must be correct and the Virtual Method Table must be
* fully equipped providing the ub_event API to be used by libunbound.
*/
struct ub_event {
/** magic must be UB_EVENT_MAGIC (0x44d74d78) */
unsigned long magic;
/** Virtual Method Table for ub_event */
struct ub_event_vmt* vmt;
};
typedef void (*ub_event_callback_t)(void*, int, void*, int, int, char*);
/**
* Create a resolving and validation context.
* The information from /etc/resolv.conf and /etc/hosts is not utilised by
* default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them.
* @param base: the pluggable event base that the caller has created.
* The unbound context uses this event base.
* @return a new context. default initialisation.
* returns NULL on error.
* You must use ub_resolve_event with this context.
* Do not call ub_ctx_async, ub_poll, ub_wait, ub_process, this is all done
* with the event_base. Setup the options you like with the other functions.
*/
struct ub_ctx* ub_ctx_create_ub_event(struct ub_event_base* base);
/**
* Create a resolving and validation context.
* The information from /etc/resolv.conf and /etc/hosts is not utilised by
* default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them.
* You have to use the same libevent that unbound was compiled with,
* otherwise it wouldn't work, the event and event_base structures would
* be different.
* @param base: the event base that the caller has created. The unbound
* context uses this event base.
* @return a new context. default initialisation.
@ -79,7 +201,10 @@ typedef void (*ub_event_callback_t)(void*, int, void*, int, int, char*);
struct ub_ctx* ub_ctx_create_event(struct event_base* base);
/**
* Set a new event_base on a context created with ub_ctx_create_event.
* Set a new libevent event_base on a context created with ub_ctx_create_event.
* You have to use the same libevent that unbound was compiled with,
* otherwise it wouldn't work, the event and event_base structures would
* be different.
* Any outbound queries will be canceled.
* @param ctx the ub_ctx to update. Must have been created with ub_ctx_create_event
* @param base the new event_base to attach to the ctx

5690
ltmain.sh

File diff suppressed because it is too large Load Diff

View File

@ -1387,7 +1387,7 @@ void comm_base_set_slow_accept_handlers(struct comm_base* ATTR_UNUSED(b),
(void)start_acc;
}
struct event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
struct ub_event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
{
/* no pipe comm possible in testbound */
return NULL;

View File

@ -40,6 +40,7 @@
*/
#include "config.h"
#include "util/netevent.h"
#include "util/ub_event.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/fptr_wlist.h"
@ -89,48 +90,29 @@
#define NUM_UDP_PER_SELECT 1
#endif
/* We define libevent structures here to hide the libevent stuff. */
#ifdef USE_MINI_EVENT
# ifdef USE_WINSOCK
# include "util/winsock_event.h"
# else
# include "util/mini_event.h"
# endif /* USE_WINSOCK */
#else /* USE_MINI_EVENT */
/* we use libevent */
# ifdef HAVE_EVENT_H
# include <event.h>
# else
# include "event2/event.h"
# include "event2/event_struct.h"
# include "event2/event_compat.h"
# endif
#endif /* USE_MINI_EVENT */
/**
* The internal event structure for keeping libevent info for the event.
* The internal event structure for keeping ub_event info for the event.
* Possibly other structures (list, tree) this is part of.
*/
struct internal_event {
/** the comm base */
struct comm_base* base;
/** libevent event type, alloced here */
struct event ev;
/** ub_event event type */
struct ub_event* ev;
};
/**
* Internal base structure, so that every thread has its own events.
*/
struct internal_base {
/** libevent event_base type. */
struct event_base* base;
/** ub_event event_base type. */
struct ub_event_base* base;
/** seconds time pointer points here */
time_t secs;
/** timeval with current time */
struct timeval now;
/** the event used for slow_accept timeouts */
struct event slow_accept;
struct ub_event* slow_accept;
/** true if slow_accept is enabled */
int slow_accept_enabled;
};
@ -139,10 +121,12 @@ struct internal_base {
* Internal timer structure, to store timer event in.
*/
struct internal_timer {
/** the super struct from which derived */
struct comm_timer super;
/** the comm base */
struct comm_base* base;
/** libevent event type, alloced here */
struct event ev;
/** ub_event event type */
struct ub_event* ev;
/** is timer enabled */
uint8_t enabled;
};
@ -151,8 +135,8 @@ struct internal_timer {
* Internal signal structure, to store signal event in.
*/
struct internal_signal {
/** libevent event type, alloced here */
struct event ev;
/** ub_event event type */
struct ub_event* ev;
/** next in signal list */
struct internal_signal* next;
};
@ -184,6 +168,8 @@ comm_base_create(int sigs)
{
struct comm_base* b = (struct comm_base*)calloc(1,
sizeof(struct comm_base));
const char *evnm="event", *evsys="", *evmethod="";
if(!b)
return NULL;
b->eb = (struct internal_base*)calloc(1, sizeof(struct internal_base));
@ -191,55 +177,20 @@ comm_base_create(int sigs)
free(b);
return NULL;
}
#ifdef USE_MINI_EVENT
(void)sigs;
/* use mini event time-sharing feature */
b->eb->base = event_init(&b->eb->secs, &b->eb->now);
#else
# if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
/* libev */
if(sigs)
b->eb->base=(struct event_base *)ev_default_loop(EVFLAG_AUTO);
else
b->eb->base=(struct event_base *)ev_loop_new(EVFLAG_AUTO);
# else
(void)sigs;
# ifdef HAVE_EVENT_BASE_NEW
b->eb->base = event_base_new();
# else
b->eb->base = event_init();
# endif
# endif
#endif
b->eb->base = ub_default_event_base(sigs, &b->eb->secs, &b->eb->now);
if(!b->eb->base) {
free(b->eb);
free(b);
return NULL;
}
comm_base_now(b);
/* avoid event_get_method call which causes crashes even when
* not printing, because its result is passed */
verbose(VERB_ALGO,
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
"libev"
#elif defined(USE_MINI_EVENT)
"event "
#else
"libevent "
#endif
"%s uses %s method.",
event_get_version(),
#ifdef HAVE_EVENT_BASE_GET_METHOD
event_base_get_method(b->eb->base)
#else
"not_obtainable"
#endif
);
ub_comm_base_now(b);
ub_get_event_sys(b->eb->base, &evnm, &evsys, &evmethod);
verbose(VERB_ALGO, "%s %s user %s method.", evnm, evsys, evmethod);
return b;
}
struct comm_base*
comm_base_create_event(struct event_base* base)
comm_base_create_event(struct ub_event_base* base)
{
struct comm_base* b = (struct comm_base*)calloc(1,
sizeof(struct comm_base));
@ -261,18 +212,12 @@ comm_base_delete(struct comm_base* b)
if(!b)
return;
if(b->eb->slow_accept_enabled) {
if(event_del(&b->eb->slow_accept) != 0) {
if(ub_event_del(b->eb->slow_accept) != 0) {
log_err("could not event_del slow_accept");
}
ub_event_free(b->eb->slow_accept);
}
#ifdef USE_MINI_EVENT
event_base_free(b->eb->base);
#elif defined(HAVE_EVENT_BASE_FREE) && defined(HAVE_EVENT_BASE_ONCE)
/* only libevent 1.2+ has it, but in 1.2 it is broken -
assertion fails on signal handling ev that is not deleted
in libevent 1.3c (event_base_once appears) this is fixed. */
event_base_free(b->eb->base);
#endif /* HAVE_EVENT_BASE_FREE and HAVE_EVENT_BASE_ONCE */
ub_event_base_free(b->eb->base);
b->eb->base = NULL;
free(b->eb);
free(b);
@ -284,9 +229,10 @@ comm_base_delete_no_base(struct comm_base* b)
if(!b)
return;
if(b->eb->slow_accept_enabled) {
if(event_del(&b->eb->slow_accept) != 0) {
if(ub_event_del(b->eb->slow_accept) != 0) {
log_err("could not event_del slow_accept");
}
ub_event_free(b->eb->slow_accept);
}
b->eb->base = NULL;
free(b->eb);
@ -304,7 +250,7 @@ void
comm_base_dispatch(struct comm_base* b)
{
int retval;
retval = event_base_dispatch(b->eb->base);
retval = ub_event_base_dispatch(b->eb->base);
if(retval != 0) {
fatal_exit("event_dispatch returned error %d, "
"errno is %s", retval, strerror(errno));
@ -313,7 +259,7 @@ comm_base_dispatch(struct comm_base* b)
void comm_base_exit(struct comm_base* b)
{
if(event_base_loopexit(b->eb->base, NULL) != 0) {
if(ub_event_base_loopexit(b->eb->base) != 0) {
log_err("Could not loopexit");
}
}
@ -326,7 +272,7 @@ void comm_base_set_slow_accept_handlers(struct comm_base* b,
b->cb_arg = arg;
}
struct event_base* comm_base_internal(struct comm_base* b)
struct ub_event_base* comm_base_internal(struct comm_base* b)
{
return b->eb->base;
}
@ -648,7 +594,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
if(!(event&EV_READ))
if(!(event&UB_EV_READ))
return;
log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
comm_base_now(rep.c->ev->base);
@ -736,7 +682,7 @@ comm_point_udp_callback(int fd, short event, void* arg)
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
if(!(event&EV_READ))
if(!(event&UB_EV_READ))
return;
log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
comm_base_now(rep.c->ev->base);
@ -839,15 +785,16 @@ int comm_point_perform_accept(struct comm_point* c,
/* set timeout, no mallocs */
tv.tv_sec = NETEVENT_SLOW_ACCEPT_TIME/1000;
tv.tv_usec = NETEVENT_SLOW_ACCEPT_TIME%1000;
event_set(&b->eb->slow_accept, -1, EV_TIMEOUT,
b->eb->slow_accept = ub_event_new(b->eb->base,
-1, UB_EV_TIMEOUT,
comm_base_handle_slow_accept, b);
if(event_base_set(b->eb->base,
&b->eb->slow_accept) != 0) {
if(b->eb->slow_accept == NULL) {
/* we do not want to log here, because
* that would spam the logfiles.
* error: "event_base_set failed." */
}
if(event_add(&b->eb->slow_accept, &tv) != 0) {
else if(ub_event_add(b->eb->slow_accept, &tv)
!= 0) {
/* we do not want to log here,
* error: "event_add failed." */
}
@ -861,7 +808,7 @@ int comm_point_perform_accept(struct comm_point* c,
WSAGetLastError() == WSAECONNRESET)
return -1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
winsock_tcp_wouldblock(&c->ev->ev, EV_READ);
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return -1;
}
log_err_addr("accept failed", wsa_strerror(WSAGetLastError()),
@ -885,14 +832,14 @@ static long win_bio_cb(BIO *b, int oper, const char* ATTR_UNUSED(argp),
if( (oper == (BIO_CB_READ|BIO_CB_RETURN) && argl == 0) ||
(oper == (BIO_CB_GETS|BIO_CB_RETURN) && argl == 0)) {
if(WSAGetLastError() == WSAEWOULDBLOCK)
winsock_tcp_wouldblock((struct event*)
BIO_get_callback_arg(b), EV_READ);
ub_winsock_tcp_wouldblock((struct ub_event*)
BIO_get_callback_arg(b), UB_EV_READ);
}
if( (oper == (BIO_CB_WRITE|BIO_CB_RETURN) && argl == 0) ||
(oper == (BIO_CB_PUTS|BIO_CB_RETURN) && argl == 0)) {
if(WSAGetLastError() == WSAEWOULDBLOCK)
winsock_tcp_wouldblock((struct event*)
BIO_get_callback_arg(b), EV_WRITE);
ub_winsock_tcp_wouldblock((struct ub_event*)
BIO_get_callback_arg(b), UB_EV_WRITE);
}
/* return original return value */
return retvalue;
@ -905,9 +852,9 @@ comm_point_tcp_win_bio_cb(struct comm_point* c, void* thessl)
SSL* ssl = (SSL*)thessl;
/* set them both just in case, but usually they are the same BIO */
BIO_set_callback(SSL_get_rbio(ssl), &win_bio_cb);
BIO_set_callback_arg(SSL_get_rbio(ssl), (char*)&c->ev->ev);
BIO_set_callback_arg(SSL_get_rbio(ssl), (char*)c->ev->ev);
BIO_set_callback(SSL_get_wbio(ssl), &win_bio_cb);
BIO_set_callback_arg(SSL_get_wbio(ssl), (char*)&c->ev->ev);
BIO_set_callback_arg(SSL_get_wbio(ssl), (char*)c->ev->ev);
}
#endif
@ -917,7 +864,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
struct comm_point* c = (struct comm_point*)arg, *c_hdl;
int new_fd;
log_assert(c->type == comm_tcp_accept);
if(!(event & EV_READ)) {
if(!(event & UB_EV_READ)) {
log_info("ignoring tcp accept event %d", (int)event);
return;
}
@ -1297,7 +1244,8 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
winsock_tcp_wouldblock(&c->ev->ev, EV_READ);
ub_winsock_tcp_wouldblock(c->ev->ev,
UB_EV_READ);
return 1;
}
log_err_addr("read (in tcp s)",
@ -1342,7 +1290,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
winsock_tcp_wouldblock(&c->ev->ev, EV_READ);
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return 1;
}
log_err_addr("read (in tcp r)",
@ -1401,7 +1349,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(error == WSAEINPROGRESS)
return 1;
else if(error == WSAEWOULDBLOCK) {
winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE);
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1;
} else if(error != 0 && verbosity < 2)
return 0;
@ -1451,7 +1399,8 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE);
ub_winsock_tcp_wouldblock(c->ev->ev,
UB_EV_WRITE);
return 1;
}
log_err_addr("tcp send s",
@ -1483,7 +1432,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE);
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1;
}
log_err_addr("tcp send r", wsa_strerror(WSAGetLastError()),
@ -1507,7 +1456,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
log_assert(c->type == comm_tcp);
comm_base_now(c->ev->base);
if(event&EV_READ) {
if(event&UB_EV_READ) {
if(!comm_point_tcp_handle_read(fd, c, 0)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@ -1519,7 +1468,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
return;
}
if(event&EV_WRITE) {
if(event&UB_EV_WRITE) {
if(!comm_point_tcp_handle_write(fd, c)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@ -1531,7 +1480,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
return;
}
if(event&EV_TIMEOUT) {
if(event&UB_EV_TIMEOUT) {
verbose(VERB_QUERY, "tcp took too long, dropped");
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@ -1550,7 +1499,7 @@ void comm_point_local_handle_callback(int fd, short event, void* arg)
log_assert(c->type == comm_local);
comm_base_now(c->ev->base);
if(event&EV_READ) {
if(event&UB_EV_READ) {
if(!comm_point_tcp_handle_read(fd, c, 1)) {
fptr_ok(fptr_whitelist_comm_point(c->callback));
(void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED,
@ -1569,7 +1518,7 @@ void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
log_assert(c->type == comm_raw);
comm_base_now(c->ev->base);
if(event&EV_TIMEOUT)
if(event&UB_EV_TIMEOUT)
err = NETEVENT_TIMEOUT;
fptr_ok(fptr_whitelist_comm_point_raw(c->callback));
(void)(*c->callback)(c, c->cb_arg, err, NULL);
@ -1609,15 +1558,16 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
c->inuse = 0;
c->callback = callback;
c->cb_arg = callback_arg;
evbits = EV_READ | EV_PERSIST;
/* libevent stuff */
event_set(&c->ev->ev, c->fd, evbits, comm_point_udp_callback, c);
if(event_base_set(base->eb->base, &c->ev->ev) != 0) {
evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_udp_callback, c);
if(c->ev->ev == NULL) {
log_err("could not baseset udp event");
comm_point_delete(c);
return NULL;
}
if(fd!=-1 && event_add(&c->ev->ev, c->timeout) != 0 ) {
if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
log_err("could not add udp event");
comm_point_delete(c);
return NULL;
@ -1660,15 +1610,16 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
c->tcp_check_nb_connect = 0;
c->callback = callback;
c->cb_arg = callback_arg;
evbits = EV_READ | EV_PERSIST;
/* libevent stuff */
event_set(&c->ev->ev, c->fd, evbits, comm_point_udp_ancil_callback, c);
if(event_base_set(base->eb->base, &c->ev->ev) != 0) {
evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_udp_ancil_callback, c);
if(c->ev->ev == NULL) {
log_err("could not baseset udp event");
comm_point_delete(c);
return NULL;
}
if(fd!=-1 && event_add(&c->ev->ev, c->timeout) != 0 ) {
if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
log_err("could not add udp event");
comm_point_delete(c);
return NULL;
@ -1725,10 +1676,11 @@ comm_point_create_tcp_handler(struct comm_base *base,
/* add to parent free list */
c->tcp_free = parent->tcp_free;
parent->tcp_free = c;
/* libevent stuff */
evbits = EV_PERSIST | EV_READ | EV_TIMEOUT;
event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_handle_callback, c);
if(event_base_set(base->eb->base, &c->ev->ev) != 0)
/* ub_event stuff */
evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_tcp_handle_callback, c);
if(c->ev->ev == NULL)
{
log_err("could not basetset tcphdl event");
parent->tcp_free = c->tcp_free;
@ -1780,17 +1732,20 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
c->tcp_check_nb_connect = 0;
c->callback = NULL;
c->cb_arg = NULL;
evbits = EV_READ | EV_PERSIST;
/* libevent stuff */
event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_accept_callback, c);
if(event_base_set(base->eb->base, &c->ev->ev) != 0 ||
event_add(&c->ev->ev, c->timeout) != 0 )
{
evbits = UB_EV_READ | UB_EV_PERSIST;
/* ub_event stuff */
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_tcp_accept_callback, c);
if(c->ev->ev == NULL) {
log_err("could not baseset tcpacc event");
comm_point_delete(c);
return NULL;
}
if (ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("could not add tcpacc event");
comm_point_delete(c);
return NULL;
}
/* now prealloc the tcp handlers */
for(i=0; i<num; i++) {
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
@ -1843,11 +1798,12 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
evbits = EV_PERSIST | EV_WRITE;
event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_handle_callback, c);
if(event_base_set(base->eb->base, &c->ev->ev) != 0)
evbits = UB_EV_PERSIST | UB_EV_WRITE;
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_tcp_handle_callback, c);
if(c->ev->ev == NULL)
{
log_err("could not basetset tcpout event");
log_err("could not baseset tcpout event");
sldns_buffer_free(c->buffer);
free(c->ev);
free(c);
@ -1895,14 +1851,19 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
c->tcp_check_nb_connect = 0;
c->callback = callback;
c->cb_arg = callback_arg;
/* libevent stuff */
evbits = EV_PERSIST | EV_READ;
event_set(&c->ev->ev, c->fd, evbits, comm_point_local_handle_callback,
c);
if(event_base_set(base->eb->base, &c->ev->ev) != 0 ||
event_add(&c->ev->ev, c->timeout) != 0 )
{
/* ub_event stuff */
evbits = UB_EV_PERSIST | UB_EV_READ;
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_local_handle_callback, c);
if(c->ev->ev == NULL) {
log_err("could not baseset localhdl event");
free(c->ev);
free(c);
return NULL;
}
if (ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("could not add localhdl event");
ub_event_free(c->ev->ev);
free(c->ev);
free(c);
return NULL;
@ -1943,16 +1904,21 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
c->tcp_check_nb_connect = 0;
c->callback = callback;
c->cb_arg = callback_arg;
/* libevent stuff */
/* ub_event stuff */
if(writing)
evbits = EV_PERSIST | EV_WRITE;
else evbits = EV_PERSIST | EV_READ;
event_set(&c->ev->ev, c->fd, evbits, comm_point_raw_handle_callback,
c);
if(event_base_set(base->eb->base, &c->ev->ev) != 0 ||
event_add(&c->ev->ev, c->timeout) != 0 )
{
evbits = UB_EV_PERSIST | UB_EV_WRITE;
else evbits = UB_EV_PERSIST | UB_EV_READ;
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_raw_handle_callback, c);
if(c->ev->ev == NULL) {
log_err("could not baseset rawhdl event");
free(c->ev);
free(c);
return NULL;
}
if (ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("could not add rawhdl event");
ub_event_free(c->ev->ev);
free(c->ev);
free(c);
return NULL;
@ -1966,7 +1932,7 @@ comm_point_close(struct comm_point* c)
if(!c)
return;
if(c->fd != -1)
if(event_del(&c->ev->ev) != 0) {
if(ub_event_del(c->ev->ev) != 0) {
log_err("could not event_del on close");
}
/* close fd after removing from event lists, or epoll.. is messed up */
@ -2002,6 +1968,7 @@ comm_point_delete(struct comm_point* c)
free(c->timeout);
if(c->type == comm_tcp || c->type == comm_local)
sldns_buffer_free(c->buffer);
ub_event_free(c->ev->ev);
free(c->ev);
free(c);
}
@ -2051,7 +2018,7 @@ void
comm_point_stop_listening(struct comm_point* c)
{
verbose(VERB_ALGO, "comm point stop listening %d", c->fd);
if(event_del(&c->ev->ev) != 0) {
if(ub_event_del(c->ev->ev) != 0) {
log_err("event_del error to stoplisten");
}
}
@ -2074,17 +2041,17 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
return;
}
}
c->ev->ev.ev_events |= EV_TIMEOUT;
ub_event_add_bits(c->ev->ev, UB_EV_TIMEOUT);
#ifndef S_SPLINT_S /* splint fails on struct timeval. */
c->timeout->tv_sec = sec;
c->timeout->tv_usec = 0;
#endif /* S_SPLINT_S */
}
if(c->type == comm_tcp) {
c->ev->ev.ev_events &= ~(EV_READ|EV_WRITE);
ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
if(c->tcp_is_reading)
c->ev->ev.ev_events |= EV_READ;
else c->ev->ev.ev_events |= EV_WRITE;
ub_event_add_bits(c->ev->ev, UB_EV_READ);
else ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
}
if(newfd != -1) {
if(c->fd != -1) {
@ -2095,9 +2062,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
#endif
}
c->fd = newfd;
c->ev->ev.ev_fd = c->fd;
ub_event_set_fd(c->ev->ev, c->fd);
}
if(event_add(&c->ev->ev, sec==0?NULL:c->timeout) != 0) {
if(ub_event_add(c->ev->ev, sec==0?NULL:c->timeout) != 0) {
log_err("event_add failed. in cpsl.");
}
}
@ -2105,13 +2072,13 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr)
{
verbose(VERB_ALGO, "comm point listen_for_rw %d %d", c->fd, wr);
if(event_del(&c->ev->ev) != 0) {
if(ub_event_del(c->ev->ev) != 0) {
log_err("event_del error to cplf");
}
c->ev->ev.ev_events &= ~(EV_READ|EV_WRITE);
if(rd) c->ev->ev.ev_events |= EV_READ;
if(wr) c->ev->ev.ev_events |= EV_WRITE;
if(event_add(&c->ev->ev, c->timeout) != 0) {
ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
if(rd) ub_event_add_bits(c->ev->ev, UB_EV_READ);
if(wr) ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
if(ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("event_add failed. in cplf.");
}
}
@ -2137,29 +2104,24 @@ size_t comm_point_get_mem(struct comm_point* c)
struct comm_timer*
comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg)
{
struct comm_timer *tm = (struct comm_timer*)calloc(1,
sizeof(struct comm_timer));
if(!tm)
return NULL;
tm->ev_timer = (struct internal_timer*)calloc(1,
struct internal_timer *tm = (struct internal_timer*)calloc(1,
sizeof(struct internal_timer));
if(!tm->ev_timer) {
if(!tm) {
log_err("malloc failed");
free(tm);
return NULL;
}
tm->ev_timer->base = base;
tm->callback = cb;
tm->cb_arg = cb_arg;
event_set(&tm->ev_timer->ev, -1, EV_TIMEOUT,
comm_timer_callback, tm);
if(event_base_set(base->eb->base, &tm->ev_timer->ev) != 0) {
tm->super.ev_timer = tm;
tm->base = base;
tm->super.callback = cb;
tm->super.cb_arg = cb_arg;
tm->ev = ub_event_new(base->eb->base, -1, UB_EV_TIMEOUT,
comm_timer_callback, &tm->super);
if(tm->ev == NULL) {
log_err("timer_create: event_base_set failed.");
free(tm->ev_timer);
free(tm);
return NULL;
}
return tm;
return &tm->super;
}
void
@ -2167,7 +2129,7 @@ comm_timer_disable(struct comm_timer* timer)
{
if(!timer)
return;
evtimer_del(&timer->ev_timer->ev);
ub_timer_del(timer->ev_timer->ev);
timer->ev_timer->enabled = 0;
}
@ -2177,12 +2139,8 @@ comm_timer_set(struct comm_timer* timer, struct timeval* tv)
log_assert(tv);
if(timer->ev_timer->enabled)
comm_timer_disable(timer);
event_set(&timer->ev_timer->ev, -1, EV_TIMEOUT,
comm_timer_callback, timer);
if(event_base_set(timer->ev_timer->base->eb->base,
&timer->ev_timer->ev) != 0)
log_err("comm_timer_set: set_base failed.");
if(evtimer_add(&timer->ev_timer->ev, tv) != 0)
if(ub_timer_add(timer->ev_timer->ev, timer->ev_timer->base->eb->base,
comm_timer_callback, timer, tv) != 0)
log_err("comm_timer_set: evtimer_add failed.");
timer->ev_timer->enabled = 1;
}
@ -2193,17 +2151,20 @@ comm_timer_delete(struct comm_timer* timer)
if(!timer)
return;
comm_timer_disable(timer);
/* Free the sub struct timer->ev_timer derived from the super struct timer.
* i.e. assert(timer == timer->ev_timer)
*/
ub_event_free(timer->ev_timer->ev);
free(timer->ev_timer);
free(timer);
}
void
comm_timer_callback(int ATTR_UNUSED(fd), short event, void* arg)
{
struct comm_timer* tm = (struct comm_timer*)arg;
if(!(event&EV_TIMEOUT))
if(!(event&UB_EV_TIMEOUT))
return;
comm_base_now(tm->ev_timer->base);
ub_comm_base_now(tm->ev_timer->base);
tm->ev_timer->enabled = 0;
fptr_ok(fptr_whitelist_comm_timer(tm->callback));
(*tm->callback)(tm->cb_arg);
@ -2218,7 +2179,7 @@ comm_timer_is_set(struct comm_timer* timer)
size_t
comm_timer_get_mem(struct comm_timer* timer)
{
return sizeof(*timer) + sizeof(struct internal_timer);
return sizeof(struct internal_timer);
}
struct comm_signal*
@ -2242,7 +2203,7 @@ void
comm_signal_callback(int sig, short event, void* arg)
{
struct comm_signal* comsig = (struct comm_signal*)arg;
if(!(event & EV_SIGNAL))
if(!(event & UB_EV_SIGNAL))
return;
comm_base_now(comsig->base);
fptr_ok(fptr_whitelist_comm_signal(comsig->callback));
@ -2260,14 +2221,16 @@ comm_signal_bind(struct comm_signal* comsig, int sig)
}
log_assert(comsig);
/* add signal event */
signal_set(&entry->ev, sig, comm_signal_callback, comsig);
if(event_base_set(comsig->base->eb->base, &entry->ev) != 0) {
log_err("Could not set signal base");
entry->ev = ub_signal_new(comsig->base->eb->base, sig,
comm_signal_callback, comsig);
if(entry->ev == NULL) {
log_err("Could not create signal event");
free(entry);
return 0;
}
if(signal_add(&entry->ev, NULL) != 0) {
if(ub_signal_add(entry->ev, NULL) != 0) {
log_err("Could not add signal handler");
ub_event_free(entry->ev);
free(entry);
return 0;
}
@ -2286,7 +2249,8 @@ comm_signal_delete(struct comm_signal* comsig)
p=comsig->ev_signal;
while(p) {
np = p->next;
signal_del(&p->ev);
ub_signal_del(p->ev);
ub_event_free(p->ev);
free(p);
p = np;
}

View File

@ -63,12 +63,12 @@
struct sldns_buffer;
struct comm_point;
struct comm_reply;
struct event_base;
struct ub_event_base;
/* internal event notification data storage structure. */
struct internal_event;
struct internal_base;
struct internal_timer;
struct internal_timer; /* A sub struct of the comm_timer super struct */
/** callback from communication point function type */
typedef int comm_point_callback_t(struct comm_point*, void*, int,
@ -265,7 +265,7 @@ struct comm_point {
* Structure only for making timeout events.
*/
struct comm_timer {
/** the internal event stuff */
/** the internal event stuff (derived) */
struct internal_timer* ev_timer;
/** callback function, takes user arg only */
@ -301,12 +301,12 @@ struct comm_signal {
struct comm_base* comm_base_create(int sigs);
/**
* Create comm base that uses the given event_base (underlying event
* mechanism pointer).
* @param base: underlying lib event base.
* Create comm base that uses the given ub_event_base (underlying pluggable
* event mechanism pointer).
* @param base: underlying pluggable event base.
* @return: the new comm base. NULL on error.
*/
struct comm_base* comm_base_create_event(struct event_base* base);
struct comm_base* comm_base_create_event(struct ub_event_base* base);
/**
* Delete comm base structure but not the underlying lib event base.
@ -357,9 +357,9 @@ void comm_base_set_slow_accept_handlers(struct comm_base* b,
/**
* Access internal data structure (for util/tube.c on windows)
* @param b: comm base
* @return event_base. Could be libevent, or internal event handler.
* @return ub_event_base.
*/
struct event_base* comm_base_internal(struct comm_base* b);
struct ub_event_base* comm_base_internal(struct comm_base* b);
/**
* Create an UDP comm point. Calls malloc.

View File

@ -44,6 +44,7 @@
#include "util/net_help.h"
#include "util/netevent.h"
#include "util/fptr_wlist.h"
#include "util/ub_event.h"
#ifndef USE_WINSOCK
/* on unix */
@ -537,7 +538,7 @@ void tube_close_write(struct tube* ATTR_UNUSED(tube))
void tube_remove_bg_listen(struct tube* tube)
{
verbose(VERB_ALGO, "tube remove_bg_listen");
winsock_unregister_wsaevent(&tube->ev_listen);
ub_winsock_unregister_wsaevent(tube->ev_listen);
}
void tube_remove_bg_write(struct tube* tube)
@ -668,8 +669,9 @@ int tube_setup_bg_listen(struct tube* tube, struct comm_base* base,
tube->listen_arg = arg;
if(!comm_base_internal(base))
return 1; /* ignore when no comm base - testing */
return winsock_register_wsaevent(comm_base_internal(base),
&tube->ev_listen, tube->event, &tube_handle_signal, tube);
tube->ev_listen = ub_winsock_register_wsaevent(
comm_base_internal(base), tube->event, &tube_handle_signal, tube);
return tube->ev_listen ? 1 : 0;
}
int tube_setup_bg_write(struct tube* ATTR_UNUSED(tube),

View File

@ -48,7 +48,6 @@ struct tube;
struct tube_res_list;
#ifdef USE_WINSOCK
#include "util/locks.h"
#include "util/winsock_event.h"
#endif
/**
@ -99,7 +98,7 @@ struct tube {
/** the windows sockets event (signaled if items in pipe) */
WSAEVENT event;
/** winsock event storage when registered with event base */
struct event ev_listen;
struct ub_event* ev_listen;
/** lock on the list of outstanding items */
lock_basic_t res_lock;

357
util/ub_event.c Normal file
View File

@ -0,0 +1,357 @@
/*
* util/ub_event.c - directly call libevent (compatability) functions
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains and implementation for the indirection layer for pluggable
* events that transparently passes it either directly to libevent, or calls
* the libevent compatibility layer functions.
*/
#include "config.h"
#include <sys/time.h>
#include "util/ub_event.h"
#include "util/log.h"
/* We define libevent structures here to hide the libevent stuff. */
#ifdef USE_MINI_EVENT
# ifdef USE_WINSOCK
# include "util/winsock_event.h"
# else
# include "util/mini_event.h"
# endif /* USE_WINSOCK */
#else /* USE_MINI_EVENT */
/* we use libevent */
# ifdef HAVE_EVENT_H
# include <event.h>
# else
# include "event2/event.h"
# include "event2/event_struct.h"
# include "event2/event_compat.h"
# endif
#endif /* USE_MINI_EVENT */
#define AS_EVENT_BASE(x) \
(((union {struct ub_event_base* a; struct event_base* b;})x).b)
#define AS_UB_EVENT_BASE(x) \
(((union {struct event_base* a; struct ub_event_base* b;})x).b)
#define AS_EVENT(x) \
(((union {struct ub_event* a; struct event* b;})x).b)
#define AS_UB_EVENT(x) \
(((union {struct event* a; struct ub_event* b;})x).b)
const char* ub_event_get_version()
{
return event_get_version();
}
void
ub_get_event_sys(struct ub_event_base* base, const char** n, const char** s,
const char** m)
{
#ifdef USE_WINSOCK
(void)base;
*n = "event";
*s = "winsock";
*m = "WSAWaitForMultipleEvents";
#elif defined(USE_MINI_EVENT)
(void)base;
*n = "mini-event";
*s = "internal";
*m = "select";
#else
struct event_base* b = AS_EVENT_BASE(base);
*s = event_get_version();
# ifdef HAVE_EVENT_BASE_GET_METHOD
*n = "libevent";
if (!b)
b = event_base_new();
*m = event_base_get_method(b);
# elif defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
*n = "libev";
if (!b)
b = (struct event_base*)ev_default_loop(EVFLAG_AUTO);
*m = ev_backend2str(ev_backend((struct ev_loop*)b));
# else
*n = "unknown";
*m = "not obtainable";
# endif
# ifdef HAVE_EVENT_BASE_FREE
if (b && b != AS_EVENT_BASE(base))
event_base_free(b);
# endif
#endif
}
struct ub_event_base*
ub_default_event_base(int sigs, time_t* time_secs, struct timeval* time_tv)
{
void* base;
(void)base;
#ifdef USE_MINI_EVENT
(void)sigs;
/* use mini event time-sharing feature */
base = event_init(time_secs, time_tv);
#else
(void)time_secs;
(void)time_tv;
# if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
/* libev */
if(sigs)
base = ev_default_loop(EVFLAG_AUTO);
else
base = ev_loop_new(EVFLAG_AUTO);
# else
(void)sigs;
# ifdef HAVE_EVENT_BASE_NEW
base = event_base_new();
# else
base = event_init();
# endif
# endif
#endif
return (struct ub_event_base*)base;
}
struct ub_event_base *
ub_libevent_event_base(struct event_base* libevent_base)
{
#ifdef USE_MINI_EVENT
return NULL;
#else
return AS_UB_EVENT_BASE(libevent_base);
#endif
}
struct event_base *
ub_libevent_get_event_base(struct ub_event_base* base)
{
#ifdef USE_MINI_EVENT
return NULL;
#else
return AS_EVENT_BASE(libevent_base);
#endif
}
void
ub_event_base_free(struct ub_event_base* base)
{
#ifdef USE_MINI_EVENT
event_base_free(AS_EVENT_BASE(base));
#elif defined(HAVE_EVENT_BASE_FREE) && defined(HAVE_EVENT_BASE_ONCE)
/* only libevent 1.2+ has it, but in 1.2 it is broken -
assertion fails on signal handling ev that is not deleted
in libevent 1.3c (event_base_once appears) this is fixed. */
event_base_free(AS_EVENT_BASE(base));
#endif /* HAVE_EVENT_BASE_FREE and HAVE_EVENT_BASE_ONCE */
}
int
ub_event_base_dispatch(struct ub_event_base* base)
{
return event_base_dispatch(AS_EVENT_BASE(base));
}
int
ub_event_base_loopexit(struct ub_event_base* base)
{
return event_base_loopexit(AS_EVENT_BASE(base), NULL);
}
struct ub_event*
ub_event_new(struct ub_event_base* base, int fd, short bits,
void (*cb)(int, short, void*), void* arg)
{
struct event *ev = (struct event*)calloc(1, sizeof(struct event));
if (!ev)
return NULL;
event_set(ev, fd, bits, cb, arg);
if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
free(ev);
return NULL;
}
return AS_UB_EVENT(ev);
}
struct ub_event*
ub_signal_new(struct ub_event_base* base, int fd,
void (*cb)(int, short, void*), void* arg)
{
struct event *ev = (struct event*)calloc(1, sizeof(struct event));
if (!ev)
return NULL;
signal_set(ev, fd, cb, arg);
if (event_base_set(AS_EVENT_BASE(base), ev) != 0) {
free(ev);
return NULL;
}
return AS_UB_EVENT(ev);
}
struct ub_event*
ub_winsock_register_wsaevent(struct ub_event_base* base, void* wsaevent,
void (*cb)(int, short, void*), void* arg)
{
#if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
struct event *ev = (struct event*)calloc(1, sizeof(struct event));
if (!ev)
return NULL;
if (winsock_register_wsaevent(AS_EVENT_BASE(base), ev, wsaevent, cb,
arg))
return AS_UB_EVENT(ev);
free(ev);
return NULL;
#else
(void)base;
(void)wsaevent;
(void)cb;
(void)arg;
return NULL;
#endif
}
void
ub_event_add_bits(struct ub_event* ev, short bits)
{
AS_EVENT(ev)->ev_events |= bits;
}
void
ub_event_del_bits(struct ub_event* ev, short bits)
{
AS_EVENT(ev)->ev_events &= ~bits;
}
void
ub_event_set_fd(struct ub_event* ev, int fd)
{
AS_EVENT(ev)->ev_fd = fd;
}
void
ub_event_free(struct ub_event* ev)
{
if (ev)
free(AS_EVENT(ev));
}
int
ub_event_add(struct ub_event* ev, struct timeval* tv)
{
return event_add(AS_EVENT(ev), tv);
}
int
ub_event_del(struct ub_event* ev)
{
return event_del(AS_EVENT(ev));
}
int
ub_timer_add(struct ub_event* ev, struct ub_event_base* base,
void (*cb)(int, short, void*), void* arg, struct timeval* tv)
{
event_set(AS_EVENT(ev), -1, UB_EV_TIMEOUT, cb, arg);
if (event_base_set(AS_EVENT_BASE(base), AS_EVENT(ev)) != 0)
return -1;
return evtimer_add(AS_EVENT(ev), tv);
}
int
ub_timer_del(struct ub_event* ev)
{
return evtimer_del(AS_EVENT(ev));
}
int
ub_signal_add(struct ub_event* ev, struct timeval* tv)
{
return signal_add(AS_EVENT(ev), tv);
}
int
ub_signal_del(struct ub_event* ev)
{
return signal_del(AS_EVENT(ev));
}
void
ub_winsock_unregister_wsaevent(struct ub_event* ev)
{
#if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
winsock_unregister_wsaevent(AS_EVENT(ev));
free(AS_EVENT(ev));
#else
(void)ev;
#endif
}
void
ub_winsock_tcp_wouldblock(struct ub_event* ev, int eventbits)
{
#if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
winsock_tcp_wouldblock(AS_EVENT(ev), eventbits);
#else
(void)ev;
(void)eventbits;
#endif
}
void ub_comm_base_now(struct comm_base* cb)
{
#ifdef USE_MINI_EVENT
/** minievent updates the time when it blocks. */
(void)cb; /* nothing to do */
#else /* !USE_MINI_EVENT */
/** fillup the time values in the event base */
time_t *tt;
struct timeval *tv;
comm_base_timept(cb, &tt, &tv);
if(gettimeofday(tv, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
}
*tt = tv->tv_sec;
#endif /* USE_MINI_EVENT */
}

127
util/ub_event.h Normal file
View File

@ -0,0 +1,127 @@
/*
* util/ub_event.h - indirection layer for pluggable events
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains prototypes for event loop functions.
*
*/
#ifndef UB_EVENT_H
#define UB_EVENT_H
struct ub_event_base;
struct ub_event;
struct comm_base;
struct event_base;
/** event timeout */
#define UB_EV_TIMEOUT 0x01
/** event fd readable */
#define UB_EV_READ 0x02
/** event fd writable */
#define UB_EV_WRITE 0x04
/** event signal */
#define UB_EV_SIGNAL 0x08
/** event must persist */
#define UB_EV_PERSIST 0x10
/** Returns event-base type. Could be "mini-event", "winsock-event" for the
* daemon compile, and will be "pluggable-event<PACKAGE_VERSION>" for
* libunbound.
*/
const char* ub_event_get_version();
/** Return the name, system and method for the pluggable event base */
void ub_get_event_sys(struct ub_event_base*, const char** n, const char** s,
const char** m);
/** Return a default event base. In the deamon thess will be the only event
* bases used.
*/
struct ub_event_base* ub_default_event_base(int, time_t*, struct timeval*);
/** Return an ub_event_base constructed for the given libevent event base */
struct ub_event_base* ub_libevent_event_base(struct event_base*);
/** Return the libevent base underlying the given ub_event_base. Will return
* NULL when the ub_event_base does not have an underlying libevent event base
*/
struct event_base* ub_libevent_get_event_base(struct ub_event_base*);
/** Free event base. Free events yourself */
void ub_event_base_free(struct ub_event_base*);
/** Run the event base */
int ub_event_base_dispatch(struct ub_event_base*);
/** exit that loop */
int ub_event_base_loopexit(struct ub_event_base*);
/** Create a new ub_event for the event base */
struct ub_event* ub_event_new(struct ub_event_base*,
int fd, short bits, void (*cb)(int, short, void*), void* arg);
/** Create a new ub_event signal for the event base */
struct ub_event* ub_signal_new(struct ub_event_base*, int fd,
void (*cb)(int, short, void*), void* arg);
/** Create a new ub_event associated with the wsaevent for the event base */
struct ub_event* ub_winsock_register_wsaevent(struct ub_event_base*,
void* wsaevent, void (*cb)(int, short, void*), void* arg);
/** Add event bits for this event to fire on */
void ub_event_add_bits(struct ub_event*, short bits);
/** Configure the event so it will not longer fire on given bits */
void ub_event_del_bits(struct ub_event*, short bits);
/** Change or set the file descriptor on the event */
void ub_event_set_fd(struct ub_event*, int fd);
/** free the event */
void ub_event_free(struct ub_event*);
/** Activate the event. The given timeval is an timeout value. */
int ub_event_add(struct ub_event*, struct timeval*);
/** Deactivate the event */
int ub_event_del(struct ub_event*);
/** Reconfigure and activate a timeout event */
int ub_timer_add(struct ub_event*, struct ub_event_base*,
void (*cb)(int, short, void*), void* arg, struct timeval*);
/** Deactivate the timeout event */
int ub_timer_del(struct ub_event*);
/** Activate a signal event */
int ub_signal_add(struct ub_event*, struct timeval*);
/** Deactivate a signal event */
int ub_signal_del(struct ub_event*);
/** Free a with a wsaevent associated event */
void ub_winsock_unregister_wsaevent(struct ub_event* ev);
/** Signal the eventloop when a TCP windows socket will block on next read
* or write (given by the eventbits)
*/
void ub_winsock_tcp_wouldblock(struct ub_event*, int bits);
/** Equip the comm_base with the current time */
void ub_comm_base_now(struct comm_base* cb);
#endif /* UB_EVENT_H */

598
util/ub_event_pluggable.c Normal file
View File

@ -0,0 +1,598 @@
/*
* util/ub_event_pluggable.c - call registered pluggable event functions
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains an implementation for the indirection layer for pluggable
* events that calls the registered pluggable event loop. It also defines a
* default pluggable event loop based on the default libevent (compatibility)
* functions.
*/
#include "config.h"
#include <sys/time.h>
#include "util/ub_event.h"
#include "libunbound/unbound-event.h"
#include "util/netevent.h"
#include "util/log.h"
#include "util/fptr_wlist.h"
/* We define libevent structures here to hide the libevent stuff. */
#ifdef USE_MINI_EVENT
# ifdef USE_WINSOCK
# include "util/winsock_event.h"
# else
# include "util/mini_event.h"
# endif /* USE_WINSOCK */
#else /* USE_MINI_EVENT */
/* we use libevent */
# ifdef HAVE_EVENT_H
# include <event.h>
# else
# include "event2/event.h"
# include "event2/event_struct.h"
# include "event2/event_compat.h"
# endif
#endif /* USE_MINI_EVENT */
struct my_event_base {
struct ub_event_base super;
struct event_base* base;
};
struct my_event {
struct ub_event super;
struct event ev;
};
#define AS_MY_EVENT_BASE(x) \
(((union {struct ub_event_base* a; struct my_event_base* b;})x).b)
#define AS_MY_EVENT(x) \
(((union {struct ub_event* a; struct my_event* b;})x).b)
const char* ub_event_get_version()
{
return "pluggable-event"PACKAGE_VERSION;
}
void
ub_get_event_sys(struct ub_event_base* base, const char** n, const char** s,
const char** m)
{
(void)base;
*n = "pluggable-event";
#ifdef USE_WINSOCK
*s = "winsock";
*m = "WSAWaitForMultipleEvents";
#elif defined(USE_MINI_EVENT)
(void)base;
*s = "internal";
*m = "select";
#else
*s = event_get_version();
# ifdef HAVE_EVENT_BASE_GET_METHOD
*n = "pluggable-libevent";
*m = event_base_get_method(b);
# elif defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
*n = "pluggable-libev";
*m = ev_backend2str(ev_backend((struct ev_loop*)b));
# else
*m = "not obtainable";
# endif
#endif
}
void
my_event_add_bits(struct ub_event* ev, short bits)
{
AS_MY_EVENT(ev)->ev.ev_events |= bits;
}
void
my_event_del_bits(struct ub_event* ev, short bits)
{
AS_MY_EVENT(ev)->ev.ev_events &= ~bits;
}
void
my_event_set_fd(struct ub_event* ev, int fd)
{
AS_MY_EVENT(ev)->ev.ev_fd = fd;
}
void
my_event_free(struct ub_event* ev)
{
free(AS_MY_EVENT(ev));
}
int
my_event_add(struct ub_event* ev, struct timeval* tv)
{
return event_add(&AS_MY_EVENT(ev)->ev, tv);
}
int
my_event_del(struct ub_event* ev)
{
return event_del(&AS_MY_EVENT(ev)->ev);
}
int
my_timer_add(struct ub_event* ev, struct ub_event_base* base,
void (*cb)(int, short, void*), void* arg, struct timeval* tv)
{
event_set(&AS_MY_EVENT(ev)->ev, -1, UB_EV_TIMEOUT, cb, arg);
if (event_base_set(AS_MY_EVENT_BASE(base)->base, &AS_MY_EVENT(ev)->ev)
!= 0)
return -1;
return evtimer_add(&AS_MY_EVENT(ev)->ev, tv);
}
int
my_timer_del(struct ub_event* ev)
{
return evtimer_del(&AS_MY_EVENT(ev)->ev);
}
int
my_signal_add(struct ub_event* ev, struct timeval* tv)
{
return signal_add(&AS_MY_EVENT(ev)->ev, tv);
}
int
my_signal_del(struct ub_event* ev)
{
return signal_del(&AS_MY_EVENT(ev)->ev);
}
void
my_winsock_unregister_wsaevent(struct ub_event* ev)
{
#if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
winsock_unregister_wsaevent(&AS_MY_EVENT(ev)->ev);
free(AS_MY_EVENT(ev));
#else
(void)ev;
#endif
}
void
my_winsock_tcp_wouldblock(struct ub_event* ev, int eventbits)
{
#if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
winsock_tcp_wouldblock(&AS_MY_EVENT(ev)->ev, eventbits);
#else
(void)ev;
(void)eventbits;
#endif
}
static struct ub_event_vmt default_event_vmt = {
my_event_add_bits, my_event_del_bits, my_event_set_fd,
my_event_free, my_event_add, my_event_del,
my_timer_add, my_timer_del, my_signal_add, my_signal_del,
my_winsock_unregister_wsaevent, my_winsock_tcp_wouldblock
};
void
my_event_base_free(struct ub_event_base* base)
{
#ifdef USE_MINI_EVENT
event_base_free(AS_MY_EVENT_BASE(base)->base);
#elif defined(HAVE_EVENT_BASE_FREE) && defined(HAVE_EVENT_BASE_ONCE)
/* only libevent 1.2+ has it, but in 1.2 it is broken -
assertion fails on signal handling ev that is not deleted
in libevent 1.3c (event_base_once appears) this is fixed. */
event_base_free(AS_MY_EVENT_BASE(base)->base);
#endif /* HAVE_EVENT_BASE_FREE and HAVE_EVENT_BASE_ONCE */
free(AS_MY_EVENT_BASE(base));
}
int
my_event_base_dispatch(struct ub_event_base* base)
{
return event_base_dispatch(AS_MY_EVENT_BASE(base)->base);
}
int
my_event_base_loopexit(struct ub_event_base* base, struct timeval* tv)
{
return event_base_loopexit(AS_MY_EVENT_BASE(base)->base, tv);
}
struct ub_event*
my_event_new(struct ub_event_base* base, int fd, short bits,
void (*cb)(int, short, void*), void* arg)
{
struct my_event *my_ev = (struct my_event*)calloc(1,
sizeof(struct my_event));
if (!my_ev)
return NULL;
event_set(&my_ev->ev, fd, bits, cb, arg);
if (event_base_set(AS_MY_EVENT_BASE(base)->base, &my_ev->ev) != 0) {
free(my_ev);
return NULL;
}
my_ev->super.magic = UB_EVENT_MAGIC;
my_ev->super.vmt = &default_event_vmt;
return &my_ev->super;
}
struct ub_event*
my_signal_new(struct ub_event_base* base, int fd,
void (*cb)(int, short, void*), void* arg)
{
struct my_event *my_ev = (struct my_event*)calloc(1,
sizeof(struct my_event));
if (!my_ev)
return NULL;
signal_set(&my_ev->ev, fd, cb, arg);
if (event_base_set(AS_MY_EVENT_BASE(base)->base, &my_ev->ev) != 0) {
free(my_ev);
return NULL;
}
my_ev->super.magic = UB_EVENT_MAGIC;
my_ev->super.vmt = &default_event_vmt;
return &my_ev->super;
}
struct ub_event*
my_winsock_register_wsaevent(struct ub_event_base* base, void* wsaevent,
void (*cb)(int, short, void*), void* arg)
{
#if defined(USE_MINI_EVENT) && defined(USE_WINSOCK)
struct my_event *my_ev = (struct my_event*)calloc(1,
sizeof(struct my_event));
if (!my_ev)
return NULL;
if (!winsock_register_wsaevent(AS_MY_EVENT_BASE(base)->base,
&my_ev->ev, wsaevent, cb, arg)) {
free(my_ev);
return NULL;
}
my_ev->super.magic = UB_EVENT_MAGIC;
my_ev->super.vmt = &default_event_vmt;
return &my_ev->super;
#else
(void)base;
(void)wsaevent;
(void)cb;
(void)arg;
return NULL;
#endif
}
static struct ub_event_base_vmt default_event_base_vmt = {
my_event_base_free, my_event_base_dispatch,
my_event_base_loopexit, my_event_new, my_signal_new,
my_winsock_register_wsaevent
};
struct ub_event_base*
ub_default_event_base(int sigs, time_t* time_secs, struct timeval* time_tv)
{
struct my_event_base* my_base = (struct my_event_base*)calloc(1,
sizeof(struct my_event_base));
if (!my_base)
return NULL;
#ifdef USE_MINI_EVENT
(void)sigs;
/* use mini event time-sharing feature */
my_base->base = event_init(time_secs, time_tv);
#else
(void)time_secs;
(void)time_tv;
# if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
/* libev */
if(sigs)
my_base->base = ev_default_loop(EVFLAG_AUTO);
else
my_base->base = ev_loop_new(EVFLAG_AUTO);
# else
(void)sigs;
# ifdef HAVE_EVENT_BASE_NEW
my_base->base = event_base_new();
# else
my_base->base = event_init();
# endif
# endif
#endif
if (!my_base->base) {
free(my_base);
return NULL;
}
my_base->super.magic = UB_EVENT_MAGIC;
my_base->super.vmt = &default_event_base_vmt;
return &my_base->super;
}
struct ub_event_base*
ub_libevent_event_base(struct event_base* base)
{
#ifdef USE_MINI_EVENT
return NULL;
#else
struct my_event_base* my_base = (struct my_event_base*)calloc(1,
sizeof(struct my_event_base));
if (!my_base)
return NULL;
my_base->super.magic = UB_EVENT_MAGIC;
my_base->super.vmt = &default_event_base_vmt;
return &my_base->super;
#endif
}
struct event_base*
ub_libevent_get_event_base(struct ub_event_base* base)
{
#ifdef USE_MINI_EVENT
return NULL;
#else
return AS_MY_EVENT_BASE(base)->base;
#endif
}
void
ub_event_base_free(struct ub_event_base* base)
{
if (base && base->magic == UB_EVENT_MAGIC) {
fptr_ok(base->vmt != &default_event_base_vmt ||
base->vmt->free == my_event_base_free);
(*base->vmt->free)(base);
}
}
int
ub_event_base_dispatch(struct ub_event_base* base)
{
if (base->magic == UB_EVENT_MAGIC) {
fptr_ok(base->vmt != &default_event_base_vmt ||
base->vmt->dispatch == my_event_base_dispatch);
return (*base->vmt->dispatch)(base);
}
return -1;
}
int
ub_event_base_loopexit(struct ub_event_base* base)
{
if (base->magic == UB_EVENT_MAGIC) {
fptr_ok(base->vmt != &default_event_base_vmt ||
base->vmt->loopexit == my_event_base_loopexit);
return (*base->vmt->loopexit)(base, NULL);
}
return -1;
}
struct ub_event*
ub_event_new(struct ub_event_base* base, int fd, short bits,
void (*cb)(int, short, void*), void* arg)
{
if (base->magic == UB_EVENT_MAGIC) {
fptr_ok(base->vmt != &default_event_base_vmt ||
base->vmt->new_event == my_event_new);
return (*base->vmt->new_event)(base, fd, bits, cb, arg);
}
return NULL;
}
struct ub_event*
ub_signal_new(struct ub_event_base* base, int fd,
void (*cb)(int, short, void*), void* arg)
{
if (base->magic == UB_EVENT_MAGIC) {
fptr_ok(base->vmt != &default_event_base_vmt ||
base->vmt->new_signal == my_signal_new);
return (*base->vmt->new_signal)(base, fd, cb, arg);
}
return NULL;
}
struct ub_event*
ub_winsock_register_wsaevent(struct ub_event_base* base, void* wsaevent,
void (*cb)(int, short, void*), void* arg)
{
if (base->magic == UB_EVENT_MAGIC) {
fptr_ok(base->vmt != &default_event_base_vmt ||
base->vmt->winsock_register_wsaevent ==
my_winsock_register_wsaevent);
return (*base->vmt->winsock_register_wsaevent)(base, wsaevent, cb, arg);
}
return NULL;
}
void
ub_event_add_bits(struct ub_event* ev, short bits)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->add_bits == my_event_add_bits);
(*ev->vmt->add_bits)(ev, bits);
}
}
void
ub_event_del_bits(struct ub_event* ev, short bits)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->del_bits == my_event_del_bits);
(*ev->vmt->del_bits)(ev, bits);
}
}
void
ub_event_set_fd(struct ub_event* ev, int fd)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->set_fd == my_event_set_fd);
(*ev->vmt->set_fd)(ev, fd);
}
}
void
ub_event_free(struct ub_event* ev)
{
if (ev && ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->free == my_event_free);
ev->vmt->free(ev);
}
}
int
ub_event_add(struct ub_event* ev, struct timeval* tv)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->add == my_event_add);
return (*ev->vmt->add)(ev, tv);
}
return -1;
}
int
ub_event_del(struct ub_event* ev)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->del == my_event_del);
return (*ev->vmt->del)(ev);
}
return -1;
}
int
ub_timer_add(struct ub_event* ev, struct ub_event_base* base,
void (*cb)(int, short, void*), void* arg, struct timeval* tv)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->add_timer == my_timer_add);
return (*ev->vmt->add_timer)(ev, base, cb, arg, tv);
}
return -1;
}
int
ub_timer_del(struct ub_event* ev)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->del_timer == my_timer_del);
return (*ev->vmt->del_timer)(ev);
}
return -1;
}
int
ub_signal_add(struct ub_event* ev, struct timeval* tv)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->add_signal == my_signal_add);
return (*ev->vmt->add_signal)(ev, tv);
}
return -1;
}
int
ub_signal_del(struct ub_event* ev)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->del_signal == my_signal_del);
return (*ev->vmt->del_signal)(ev);
}
return -1;
}
void
ub_winsock_unregister_wsaevent(struct ub_event* ev)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->winsock_unregister_wsaevent ==
my_winsock_unregister_wsaevent);
(*ev->vmt->winsock_unregister_wsaevent)(ev);
}
}
void
ub_winsock_tcp_wouldblock(struct ub_event* ev, int eventbits)
{
if (ev->magic == UB_EVENT_MAGIC) {
fptr_ok(ev->vmt != &default_event_vmt ||
ev->vmt->winsock_tcp_wouldblock ==
my_winsock_tcp_wouldblock);
(*ev->vmt->winsock_tcp_wouldblock)(ev, eventbits);
}
}
void ub_comm_base_now(struct comm_base* cb)
{
time_t *tt;
struct timeval *tv;
#ifdef USE_MINI_EVENT
/** minievent updates the time when it blocks. */
if (comm_base_internal(cb)->magic == UB_EVENT_MAGIC &&
comm_base_internal(cb)->vmt == &default_event_base_vmt)
return; /* Actually using mini event, so do not set time */
#endif /* USE_MINI_EVENT */
/** fillup the time values in the event base */
comm_base_timept(cb, &tt, &tv);
if(gettimeofday(tv, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
}
*tt = tv->tv_sec;
}

View File

@ -51,7 +51,7 @@
#include "daemon/remote.h"
#include "util/config_file.h"
#include "util/netevent.h"
#include "util/winsock_event.h"
#include "util/ub_event.h"
/** global service status */
static SERVICE_STATUS service_status;
@ -60,7 +60,7 @@ static SERVICE_STATUS_HANDLE service_status_handle;
/** global service stop event */
static WSAEVENT service_stop_event = NULL;
/** event struct for stop callbacks */
static struct event service_stop_ev;
static struct event* service_stop_ev = NULL;
/** if stop even means shutdown or restart */
static int service_stop_shutdown = 0;
/** config file to open. global communication to service_main() */
@ -600,9 +600,9 @@ void wsvc_setup_worker(struct worker* worker)
/* if not started with -w service, do nothing */
if(!service_stop_event)
return;
if(!winsock_register_wsaevent(comm_base_internal(worker->base),
&service_stop_ev, service_stop_event,
&worker_win_stop_cb, worker)) {
if(!(service_stop_ev = ub_winsock_register_wsaevent(
comm_base_internal(worker->base), service_stop_event,
&worker_win_stop_cb, worker))) {
fatal_exit("could not register wsaevent");
return;
}