mirror of https://github.com/getdnsapi/getdns.git
libevent & libev following new extension scheme
This commit is contained in:
parent
1f203485e2
commit
b3b634a2f5
|
@ -759,11 +759,11 @@ getdns_context_request_count_changed(getdns_context *context, uint32_t prev_rc)
|
|||
return;
|
||||
|
||||
if (context->outbound_requests->count)
|
||||
context->extension->functions->schedule_read(
|
||||
context->extension->vmt->schedule_read(
|
||||
context->extension, ub_fd(context->unbound_ctx),
|
||||
TIMEOUT_FOREVER, &context->ub_event);
|
||||
else
|
||||
context->extension->functions->clear_read(
|
||||
context->extension->vmt->clear_read(
|
||||
context->extension, &context->ub_event);
|
||||
}
|
||||
|
||||
|
@ -1886,7 +1886,7 @@ getdns_context_detach_eventloop(struct getdns_context* context)
|
|||
context->processing = 1;
|
||||
/* cancel all outstanding requests */
|
||||
cancel_outstanding_requests(context, 1);
|
||||
r = context->extension->functions->cleanup(context->extension);
|
||||
r = context->extension->vmt->cleanup(context->extension);
|
||||
if (r == GETDNS_RETURN_GOOD) {
|
||||
context->extension = &context->mini_event.loop;
|
||||
r = getdns_mini_event_init(context, &context->mini_event);
|
||||
|
@ -1924,7 +1924,7 @@ getdns_context_schedule_timeout(getdns_context *context, uint64_t timeout,
|
|||
el_ev->timeout_cb = callback;
|
||||
el_ev->ev = NULL;
|
||||
|
||||
return context->extension->functions->schedule_timeout(
|
||||
return context->extension->vmt->schedule_timeout(
|
||||
context->extension, timeout, el_ev);
|
||||
}
|
||||
|
||||
|
@ -1937,7 +1937,7 @@ getdns_context_clear_timeout(getdns_context* context,
|
|||
RETURN_IF_NULL(el_ev->timeout_cb, GETDNS_RETURN_GOOD);
|
||||
|
||||
if (el_ev->timeout_cb) {
|
||||
context->extension->functions->clear_timeout(
|
||||
context->extension->vmt->clear_timeout(
|
||||
context->extension, el_ev);
|
||||
el_ev->timeout_cb = NULL;
|
||||
}
|
||||
|
@ -2110,4 +2110,10 @@ getdns_context_local_namespace_resolve(getdns_dns_req* req,
|
|||
|
||||
}
|
||||
|
||||
struct mem_funcs *
|
||||
priv_getdns_context_mf(getdns_context *context)
|
||||
{
|
||||
return &context->mf;
|
||||
}
|
||||
|
||||
/* context.c */
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <stdio.h>
|
||||
#include "getdns/getdns_ext_libev.h"
|
||||
#include "config.h"
|
||||
#include "types-internal.h"
|
||||
|
||||
#ifdef HAVE_LIBEV_EV_H
|
||||
#include <libev/ev.h>
|
||||
|
@ -46,119 +47,138 @@
|
|||
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
||||
/* extension info */
|
||||
struct getdns_libev_data {
|
||||
struct ev_loop* loop;
|
||||
struct ev_io* poll_handle;
|
||||
};
|
||||
typedef struct getdns_libev {
|
||||
getdns_eventloop_vmt *vmt;
|
||||
struct ev_loop *loop;
|
||||
struct mem_funcs mf;
|
||||
} getdns_libev;
|
||||
|
||||
static void
|
||||
request_count_changed(uint32_t request_count, struct getdns_libev_data *ev_data) {
|
||||
if (request_count > 0) {
|
||||
ev_io_start(ev_data->loop, ev_data->poll_handle);
|
||||
} else {
|
||||
ev_io_stop(ev_data->loop, ev_data->poll_handle);
|
||||
}
|
||||
}
|
||||
static getdns_return_t getdns_libev_cleanup(getdns_eventloop *loop);
|
||||
static getdns_return_t getdns_libev_schedule_read(getdns_eventloop *loop,
|
||||
int fd, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
static getdns_return_t getdns_libev_schedule_timeout
|
||||
(getdns_eventloop *loop, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
static getdns_return_t getdns_libev_clear_event
|
||||
(getdns_eventloop *loop, getdns_eventloop_event *ev);
|
||||
|
||||
/* lib ev callbacks */
|
||||
static void
|
||||
getdns_libev_cb(struct ev_loop *loop, struct ev_io *handle, int revents) {
|
||||
struct getdns_context* context = (struct getdns_context*) handle->data;
|
||||
if (getdns_context_process_async(context) == GETDNS_RETURN_BAD_CONTEXT) {
|
||||
// context destroyed
|
||||
return;
|
||||
}
|
||||
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
||||
struct getdns_libev_data* ev_data =
|
||||
(struct getdns_libev_data*) getdns_context_get_extension_data(context);
|
||||
request_count_changed(rc, ev_data);
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_libev_timeout_cb(struct ev_loop *loop, struct ev_timer* handle, int status) {
|
||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) handle->data;
|
||||
timeout_data->callback(timeout_data->userarg);
|
||||
}
|
||||
|
||||
/* getdns extension functions */
|
||||
static getdns_return_t
|
||||
getdns_libev_request_count_changed(struct getdns_context* context,
|
||||
uint32_t request_count, void* eventloop_data) {
|
||||
struct getdns_libev_data *ev_data = (struct getdns_libev_data*) eventloop_data;
|
||||
request_count_changed(request_count, ev_data);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libev_cleanup(struct getdns_context* context, void* data) {
|
||||
struct getdns_libev_data *ev_data = (struct getdns_libev_data*) data;
|
||||
ev_io_stop(ev_data->loop, ev_data->poll_handle);
|
||||
free(ev_data->poll_handle);
|
||||
free(ev_data);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libev_schedule_timeout(struct getdns_context* context,
|
||||
void* eventloop_data, uint64_t timeout,
|
||||
getdns_timeout_data_t* timeout_data)
|
||||
{
|
||||
struct ev_timer *timer;
|
||||
struct getdns_libev_data* ev_data = (struct getdns_libev_data*) eventloop_data;
|
||||
ev_tstamp to = timeout;
|
||||
to /= 1000;
|
||||
timer = (struct ev_timer*) malloc(sizeof(struct ev_timer));
|
||||
ev_timer_init(timer, getdns_libev_timeout_cb, to, 0);
|
||||
timer->data = timeout_data;
|
||||
timeout_data->extension_timer = timer;
|
||||
ev_timer_start(ev_data->loop, timer);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libev_clear_timeout(struct getdns_context* context,
|
||||
void* eventloop_data, void* eventloop_timer) {
|
||||
struct ev_timer* timer = (struct ev_timer*) eventloop_timer;
|
||||
struct getdns_libev_data* ev_data = (struct getdns_libev_data*) eventloop_data;
|
||||
ev_timer_stop(ev_data->loop, timer);
|
||||
free(timer);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
static getdns_eventloop_extension LIBEV_EXT = {
|
||||
static getdns_eventloop_vmt getdns_libev_vmt = {
|
||||
getdns_libev_cleanup,
|
||||
getdns_libev_schedule_read,
|
||||
getdns_libev_clear_event,
|
||||
getdns_libev_schedule_timeout,
|
||||
getdns_libev_clear_timeout,
|
||||
getdns_libev_request_count_changed
|
||||
getdns_libev_clear_event,
|
||||
};
|
||||
|
||||
/*
|
||||
* getdns_extension_set_libev_loop
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_extension_set_libev_loop(struct getdns_context *context,
|
||||
getdns_extension_set_libev_loop(getdns_context *context,
|
||||
struct ev_loop *loop)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(loop, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* TODO: cleanup current extension base */
|
||||
getdns_return_t r = getdns_extension_detach_eventloop(context);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return r;
|
||||
}
|
||||
struct getdns_libev_data* ev_data = (struct getdns_libev_data*) malloc(sizeof(struct getdns_libev_data));
|
||||
if (!ev_data) {
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
}
|
||||
int fd = getdns_context_fd(context);
|
||||
ev_data->poll_handle = (struct ev_io*) malloc(sizeof(struct ev_io));
|
||||
ev_io_init(ev_data->poll_handle, getdns_libev_cb, fd, EV_READ);
|
||||
ev_data->loop = loop;
|
||||
getdns_libev *ext;
|
||||
getdns_return_t r;
|
||||
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
RETURN_IF_NULL(loop, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
if ((r = getdns_context_detach_eventloop(context)))
|
||||
return r;
|
||||
|
||||
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libev);
|
||||
ext->vmt = &getdns_libev_vmt;
|
||||
ext->loop = loop;
|
||||
ext->mf = *priv_getdns_context_mf(context);
|
||||
|
||||
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libev_cleanup(getdns_eventloop *loop)
|
||||
{
|
||||
getdns_libev *ext = (getdns_libev *)loop;
|
||||
|
||||
GETDNS_FREE(ext->mf, ext);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_libev_read_cb(struct ev_loop *l, struct ev_io *io, int revents)
|
||||
{
|
||||
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data;
|
||||
assert(el_ev->read_cb);
|
||||
el_ev->read_cb(el_ev->userarg);
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_libev_timeout_cb(struct ev_loop *l, struct ev_timer *timer, int revent)
|
||||
{
|
||||
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
|
||||
assert(el_ev->timeout_cb);
|
||||
el_ev->timeout_cb(el_ev->userarg);
|
||||
}
|
||||
|
||||
typedef struct io_timer {
|
||||
ev_io io;
|
||||
ev_timer timer;
|
||||
} io_timer;
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libev_schedule_read(getdns_eventloop *loop,
|
||||
int fd, uint64_t timeout, getdns_eventloop_event *el_ev)
|
||||
{
|
||||
getdns_libev *ext = (getdns_libev *)loop;
|
||||
io_timer *my_ev;
|
||||
ev_io *my_io;
|
||||
ev_timer *my_timer;
|
||||
ev_tstamp to = ((ev_tstamp)timeout) / 1000;
|
||||
|
||||
if (fd < 0) el_ev->read_cb = NULL;
|
||||
if (timeout == TIMEOUT_FOREVER) el_ev->timeout_cb = NULL;
|
||||
|
||||
if (!el_ev->read_cb && !el_ev->timeout_cb)
|
||||
return GETDNS_RETURN_GOOD; /* Nothing to schedule */
|
||||
|
||||
if (!(my_ev = GETDNS_MALLOC(ext->mf, io_timer)))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
el_ev->ev = my_ev;
|
||||
|
||||
if (el_ev->read_cb) {
|
||||
my_io = &my_ev->io;
|
||||
my_io->data = el_ev;
|
||||
ev_io_init(my_io, getdns_libev_read_cb, fd, EV_READ);
|
||||
ev_io_start(ext->loop, &my_ev->io);
|
||||
}
|
||||
if (el_ev->timeout_cb) {
|
||||
my_timer = &my_ev->timer;
|
||||
my_timer->data = el_ev;
|
||||
ev_timer_init(my_timer, getdns_libev_timeout_cb, to, 0);
|
||||
ev_timer_start(ext->loop, &my_ev->timer);
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libev_schedule_timeout(getdns_eventloop *loop,
|
||||
uint64_t timeout, getdns_eventloop_event *el_ev)
|
||||
{
|
||||
return getdns_libev_schedule_read(loop, -1, timeout, el_ev);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libev_clear_event(getdns_eventloop *loop,
|
||||
getdns_eventloop_event *el_ev)
|
||||
{
|
||||
getdns_libev *ext = (getdns_libev *)loop;
|
||||
io_timer *my_ev = (io_timer *)el_ev->ev;
|
||||
|
||||
assert(my_ev);
|
||||
|
||||
if (el_ev->read_cb)
|
||||
ev_io_stop(ext->loop, &my_ev->io);
|
||||
if (el_ev->timeout_cb)
|
||||
ev_timer_stop(ext->loop, &my_ev->timer);
|
||||
|
||||
GETDNS_FREE(ext->mf, el_ev->ev);
|
||||
el_ev->ev = NULL;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
ev_data->poll_handle->data = context;
|
||||
return getdns_extension_set_eventloop(context, &LIBEV_EXT, ev_data);
|
||||
} /* getdns_extension_set_libev_loop */
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <sys/time.h>
|
||||
#include "getdns/getdns_ext_libevent.h"
|
||||
#include "config.h"
|
||||
#include "types-internal.h"
|
||||
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
|
@ -59,132 +60,139 @@ static struct event *
|
|||
event_new(struct event_base *b, evutil_socket_t fd, short ev, void* cb, void *arg)
|
||||
{
|
||||
struct event* e = (struct event*)calloc(1, sizeof(struct event));
|
||||
if(!e) return NULL;
|
||||
|
||||
if (!e) return NULL;
|
||||
event_set(e, fd, ev, cb, arg);
|
||||
event_base_set(b, e);
|
||||
return e;
|
||||
}
|
||||
|
||||
static struct event_base *
|
||||
event_get_base(const struct event *ev)
|
||||
{
|
||||
return ev->base;
|
||||
}
|
||||
|
||||
static evutil_socket_t df
|
||||
event_get_fd(const struct event *ev)
|
||||
{
|
||||
return ev->fd;
|
||||
}
|
||||
#endif /* no event2 */
|
||||
|
||||
/* extension info */
|
||||
struct event_data {
|
||||
struct event* event;
|
||||
struct event_base* event_base;
|
||||
};
|
||||
typedef struct getdns_libevent {
|
||||
getdns_eventloop_vmt *vmt;
|
||||
struct event_base *base;
|
||||
struct mem_funcs mf;
|
||||
} getdns_libevent;
|
||||
|
||||
static void
|
||||
request_count_changed(uint32_t request_count, struct event_data *ev_data) {
|
||||
if (request_count > 0) {
|
||||
event_add(ev_data->event, NULL);
|
||||
} else {
|
||||
event_del(ev_data->event);
|
||||
}
|
||||
}
|
||||
static getdns_return_t getdns_libevent_cleanup(getdns_eventloop *loop);
|
||||
static getdns_return_t getdns_libevent_schedule_read(getdns_eventloop *loop,
|
||||
int fd, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
static getdns_return_t getdns_libevent_schedule_timeout
|
||||
(getdns_eventloop *loop, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
static getdns_return_t getdns_libevent_clear_event
|
||||
(getdns_eventloop *loop, getdns_eventloop_event *ev);
|
||||
|
||||
/* lib event callbacks */
|
||||
static void
|
||||
getdns_libevent_cb(evutil_socket_t fd, short what, void *userarg) {
|
||||
struct getdns_context* context = (struct getdns_context*) userarg;
|
||||
if (getdns_context_process_async(context) == GETDNS_RETURN_BAD_CONTEXT) {
|
||||
// context destroyed
|
||||
return;
|
||||
}
|
||||
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
||||
struct event_data* ev_data =
|
||||
(struct event_data*) getdns_context_get_extension_data(context);
|
||||
request_count_changed(rc, ev_data);
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_libevent_timeout_cb(evutil_socket_t fd, short what, void* userarg) {
|
||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) userarg;
|
||||
timeout_data->callback(timeout_data->userarg);
|
||||
}
|
||||
|
||||
/* getdns extension functions */
|
||||
static getdns_return_t
|
||||
getdns_libevent_request_count_changed(struct getdns_context* context,
|
||||
uint32_t request_count, void* eventloop_data) {
|
||||
struct event_data *edata = (struct event_data*) eventloop_data;
|
||||
request_count_changed(request_count, edata);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_cleanup(struct getdns_context* context, void* data) {
|
||||
struct event_data *edata = (struct event_data*) data;
|
||||
event_del(edata->event);
|
||||
event_free(edata->event);
|
||||
free(edata);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_schedule_timeout(struct getdns_context* context,
|
||||
void* eventloop_data, uint64_t timeout,
|
||||
getdns_timeout_data_t* timeout_data)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct event* ev = NULL;
|
||||
struct event_data* ev_data = (struct event_data*) eventloop_data;
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
ev = evtimer_new(ev_data->event_base, getdns_libevent_timeout_cb, timeout_data);
|
||||
timeout_data->extension_timer = ev;
|
||||
evtimer_add(ev, &tv);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_clear_timeout(struct getdns_context* context,
|
||||
void* eventloop_data, void* eventloop_timer) {
|
||||
struct event* ev = (struct event*) eventloop_timer;
|
||||
event_del(ev);
|
||||
event_free(ev);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
static getdns_eventloop_extension LIBEVENT_EXT = {
|
||||
static getdns_eventloop_vmt getdns_libevent_vmt = {
|
||||
getdns_libevent_cleanup,
|
||||
getdns_libevent_schedule_read,
|
||||
getdns_libevent_clear_event,
|
||||
getdns_libevent_schedule_timeout,
|
||||
getdns_libevent_clear_timeout,
|
||||
getdns_libevent_request_count_changed
|
||||
getdns_libevent_clear_event,
|
||||
};
|
||||
|
||||
/*
|
||||
* getdns_extension_set_libevent_base
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base * this_event_base)
|
||||
getdns_extension_set_libevent_base(getdns_context *context,
|
||||
struct event_base *base)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
RETURN_IF_NULL(this_event_base, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* TODO: cleanup current extension base */
|
||||
getdns_return_t r = getdns_extension_detach_eventloop(context);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return r;
|
||||
}
|
||||
int fd = getdns_context_fd(context);
|
||||
struct event* getdns_event = event_new(this_event_base, fd, EV_READ | EV_PERSIST, getdns_libevent_cb, context);
|
||||
if (!getdns_event) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
getdns_libevent *ext;
|
||||
getdns_return_t r;
|
||||
|
||||
/* TODO: use context functs? */
|
||||
struct event_data* ev_data = (struct event_data*) malloc(sizeof(struct event_data));
|
||||
if (!ev_data) {
|
||||
/* cleanup */
|
||||
event_del(getdns_event);
|
||||
event_free(getdns_event);
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
RETURN_IF_NULL(base, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
if ((r = getdns_context_detach_eventloop(context)))
|
||||
return r;
|
||||
|
||||
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libevent);
|
||||
ext->vmt = &getdns_libevent_vmt;
|
||||
ext->base = base;
|
||||
ext->mf = *priv_getdns_context_mf(context);
|
||||
|
||||
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_cleanup(getdns_eventloop *loop)
|
||||
{
|
||||
getdns_libevent *ext = (getdns_libevent *)loop;
|
||||
|
||||
GETDNS_FREE(ext->mf, ext);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_libevent_callback(evutil_socket_t fd, short bits, void *arg)
|
||||
{
|
||||
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)arg;
|
||||
|
||||
if (bits & EV_READ) {
|
||||
assert(el_ev->read_cb);
|
||||
el_ev->read_cb(el_ev->userarg);
|
||||
} else if (bits & EV_TIMEOUT) {
|
||||
assert(el_ev->timeout_cb);
|
||||
el_ev->timeout_cb(el_ev->userarg);
|
||||
} else
|
||||
assert(ASSERT_UNREACHABLE);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_schedule_read(getdns_eventloop *loop,
|
||||
int fd, uint64_t timeout, getdns_eventloop_event *el_ev)
|
||||
{
|
||||
getdns_libevent *ext = (getdns_libevent *)loop;
|
||||
struct event *my_ev;
|
||||
struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };
|
||||
short bits = ((fd >= 0 && el_ev->read_cb ? EV_READ|EV_PERSIST : 0) |
|
||||
(timeout != TIMEOUT_FOREVER && el_ev->timeout_cb ? EV_TIMEOUT : 0));
|
||||
|
||||
if (!bits)
|
||||
return GETDNS_RETURN_GOOD; /* Nothing to schedule */
|
||||
|
||||
if (!(my_ev = event_new(
|
||||
ext->base, fd, bits, getdns_libevent_callback, el_ev)))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
el_ev->ev = my_ev;
|
||||
if (event_add(my_ev,
|
||||
(timeout != TIMEOUT_FOREVER && el_ev->timeout_cb ? &tv : NULL)))
|
||||
goto error;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
error:
|
||||
event_free(my_ev);
|
||||
el_ev->ev = NULL;
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
ev_data->event = getdns_event;
|
||||
ev_data->event_base = this_event_base;
|
||||
return getdns_extension_set_eventloop(context, &LIBEVENT_EXT, ev_data);
|
||||
} /* getdns_extension_set_libevent_base */
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_schedule_timeout(getdns_eventloop *loop,
|
||||
uint64_t timeout, getdns_eventloop_event *el_ev)
|
||||
{
|
||||
return getdns_libevent_schedule_read(loop, -1, timeout, el_ev);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_clear_event(getdns_eventloop *loop,
|
||||
getdns_eventloop_event *el_ev)
|
||||
{
|
||||
assert(el_ev->ev);
|
||||
|
||||
if (event_del(el_ev->ev) != 0)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
event_free(el_ev->ev);
|
||||
el_ev->ev = NULL;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ static getdns_return_t getdns_mini_event_schedule_timeout
|
|||
static getdns_return_t getdns_mini_event_clear_event
|
||||
(getdns_eventloop *loop, getdns_eventloop_event *ev);
|
||||
|
||||
static getdns_eventloop_functions getdns_mini_event_functions = {
|
||||
static getdns_eventloop_vmt getdns_mini_event_vmt = {
|
||||
getdns_mini_event_cleanup,
|
||||
getdns_mini_event_schedule_read,
|
||||
getdns_mini_event_clear_event,
|
||||
|
@ -63,7 +63,7 @@ getdns_mini_event_init(getdns_context *context, getdns_mini_event *ext)
|
|||
if (!context) return GETDNS_RETURN_BAD_CONTEXT;
|
||||
if (!ext) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
ext->loop.functions = &getdns_mini_event_functions;
|
||||
ext->loop.vmt = &getdns_mini_event_vmt;
|
||||
ext->base = getdns_event_init(&ext->time_secs, &ext->time_tv);
|
||||
if (!ext->base)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
@ -86,7 +86,7 @@ void
|
|||
getdns_mini_event_destroy(getdns_mini_event *ext)
|
||||
{
|
||||
if (ext) {
|
||||
ext->loop.functions->cleanup(&ext->loop);
|
||||
ext->loop.vmt->cleanup(&ext->loop);
|
||||
GETDNS_FREE(ext->mf, ext);
|
||||
}
|
||||
}
|
||||
|
@ -158,17 +158,25 @@ getdns_mini_event_schedule_read(getdns_eventloop *loop,
|
|||
if (!bits)
|
||||
return GETDNS_RETURN_GOOD; /* Nothing to schedule */
|
||||
|
||||
my_ev = GETDNS_MALLOC(ext->mf, struct getdns_event);
|
||||
if (!(my_ev = GETDNS_MALLOC(ext->mf, struct getdns_event)))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
el_ev->ev = my_ev;
|
||||
getdns_event_set(my_ev, fd, bits, getdns_mini_event_callback, el_ev);
|
||||
|
||||
if (getdns_mini_event_settime(ext))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
goto error;
|
||||
|
||||
(void) getdns_event_base_set(ext->base, my_ev);
|
||||
if (getdns_event_add(my_ev, &tv))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
if (getdns_event_add(my_ev, (
|
||||
timeout != TIMEOUT_FOREVER && el_ev->timeout_cb ? &tv : NULL)))
|
||||
goto error;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
error:
|
||||
GETDNS_FREE(ext->mf, my_ev);
|
||||
el_ev->ev = NULL;
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
|
|
|
@ -81,9 +81,9 @@ typedef struct getdns_eventloop_event {
|
|||
void *ev;
|
||||
} getdns_eventloop_event;
|
||||
|
||||
typedef struct getdns_eventloop_functions getdns_eventloop_functions;
|
||||
typedef struct getdns_eventloop_vmt getdns_eventloop_vmt;
|
||||
typedef struct getdns_eventloop {
|
||||
getdns_eventloop_functions *functions;
|
||||
getdns_eventloop_vmt *vmt;
|
||||
} getdns_eventloop;
|
||||
|
||||
/* Call the extension to clean up data allocated on initialization. */
|
||||
|
@ -118,7 +118,8 @@ typedef getdns_return_t (*getdns_eventloop_schedule_timeout)
|
|||
typedef getdns_return_t (*getdns_eventloop_clear_timeout)
|
||||
(getdns_eventloop *loop, getdns_eventloop_event *ev);
|
||||
|
||||
struct getdns_eventloop_functions {
|
||||
/* Virtual Method Table */
|
||||
struct getdns_eventloop_vmt {
|
||||
getdns_eventloop_cleanup cleanup;
|
||||
getdns_eventloop_schedule_read schedule_read;
|
||||
getdns_eventloop_clear_read clear_read;
|
||||
|
|
|
@ -125,6 +125,9 @@ struct mem_funcs {
|
|||
mf_union mf;
|
||||
};
|
||||
|
||||
struct mem_funcs *
|
||||
priv_getdns_context_mf(getdns_context *context);
|
||||
|
||||
typedef enum network_req_state_enum
|
||||
{
|
||||
NET_REQ_NOT_SENT,
|
||||
|
@ -248,7 +251,6 @@ getdns_dns_req *dns_req_new(struct getdns_context *context,
|
|||
|
||||
void dns_req_free(getdns_dns_req * req);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* types-internal.h */
|
||||
|
|
Loading…
Reference in New Issue