summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2012-09-03 19:25:48 -0400
committerGreg Hudson <ghudson@mit.edu>2012-09-03 19:25:48 -0400
commit6b60871d961eff2fa4c476867ae9d8cbcffb8953 (patch)
tree86b466bd04d500f57b58ae90d75c9160380ab253 /src
parentfe285ec16b65ac6177a404baa635c1d09054dc81 (diff)
downloadkrb5-6b60871d961eff2fa4c476867ae9d8cbcffb8953.tar.gz
krb5-6b60871d961eff2fa4c476867ae9d8cbcffb8953.tar.xz
krb5-6b60871d961eff2fa4c476867ae9d8cbcffb8953.zip
Update bundled libverto to 0.2.5
Diffstat (limited to 'src')
-rw-r--r--src/util/k5ev/verto-k5ev.c41
-rw-r--r--src/util/k5ev/verto-libev.c41
-rw-r--r--src/util/verto/libverto.exports4
-rw-r--r--src/util/verto/module.c49
-rw-r--r--src/util/verto/verto-module.h21
-rw-r--r--src/util/verto/verto.c192
-rw-r--r--src/util/verto/verto.h78
7 files changed, 363 insertions, 63 deletions
diff --git a/src/util/k5ev/verto-k5ev.c b/src/util/k5ev/verto-k5ev.c
index bd3003b04f..35c94d66ed 100644
--- a/src/util/k5ev/verto-k5ev.c
+++ b/src/util/k5ev/verto-k5ev.c
@@ -94,12 +94,40 @@ k5ev_ctx_reinitialize(verto_mod_ctx *ctx)
static void
libev_callback(EV_P_ ev_watcher *w, int revents)
{
- if (verto_get_type(w->data) == VERTO_EV_TYPE_CHILD)
+ verto_ev_flag state = VERTO_EV_FLAG_NONE;
+
+ if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
+ if (revents & EV_READ)
+ state |= VERTO_EV_FLAG_IO_READ;
+ if (revents & EV_WRITE)
+ state |= VERTO_EV_FLAG_IO_WRITE;
+ if (revents & EV_ERROR)
+ state |= VERTO_EV_FLAG_IO_ERROR;
+
+ verto_set_fd_state(w->data, state);
verto_fire(w->data);
}
+static void
+k5ev_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,
+ verto_mod_ev *evpriv)
+{
+ if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
+ int events = EV_NONE;
+
+ if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
+ events |= EV_READ;
+ if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
+ events |= EV_WRITE;
+
+ ev_io_stop(ctx, (ev_io*) evpriv);
+ ev_io_set(((ev_io*) evpriv), verto_get_fd(ev), events);
+ ev_io_start(ctx, (ev_io*) evpriv);
+ }
+}
+
#define setuptype(type, ...) \
w.type = malloc(sizeof(ev_ ## type)); \
if (w.type) { \
@@ -120,17 +148,12 @@ k5ev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
ev_child *child;
} w;
ev_tstamp interval;
- int events = EV_NONE;
w.watcher = NULL;
*flags |= VERTO_EV_FLAG_PERSIST;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
- if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
- events |= EV_READ;
- if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
- events |= EV_WRITE;
- setuptype(io, libev_callback, verto_get_fd(ev), events);
+ setuptype(io, libev_callback, verto_get_fd(ev), EV_NONE);
case VERTO_EV_TYPE_TIMEOUT:
interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0;
setuptype(timer, libev_callback, interval, interval);
@@ -145,8 +168,10 @@ k5ev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
break; /* Not supported */
}
- if (w.watcher)
+ if (w.watcher) {
w.watcher->data = (void*) ev;
+ k5ev_ctx_set_flags(ctx, ev, w.watcher);
+ }
return w.watcher;
}
diff --git a/src/util/k5ev/verto-libev.c b/src/util/k5ev/verto-libev.c
index 4e6e816b9f..9c7c32449c 100644
--- a/src/util/k5ev/verto-libev.c
+++ b/src/util/k5ev/verto-libev.c
@@ -78,12 +78,40 @@ libev_ctx_reinitialize(verto_mod_ctx *ctx)
static void
libev_callback(EV_P_ ev_watcher *w, int revents)
{
- if (verto_get_type(w->data) == VERTO_EV_TYPE_CHILD)
+ verto_ev_flag state = VERTO_EV_FLAG_NONE;
+
+ if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
+ if (revents & EV_READ)
+ state |= VERTO_EV_FLAG_IO_READ;
+ if (revents & EV_WRITE)
+ state |= VERTO_EV_FLAG_IO_WRITE;
+ if (revents & EV_ERROR)
+ state |= VERTO_EV_FLAG_IO_ERROR;
+
+ verto_set_fd_state(w->data, state);
verto_fire(w->data);
}
+static void
+libev_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,
+ verto_mod_ev *evpriv)
+{
+ if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
+ int events = EV_NONE;
+
+ if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
+ events |= EV_READ;
+ if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
+ events |= EV_WRITE;
+
+ ev_io_stop(ctx, (ev_io*) evpriv);
+ ev_io_set(((ev_io*) evpriv), verto_get_fd(ev), events);
+ ev_io_start(ctx, (ev_io*) evpriv);
+ }
+}
+
#define setuptype(type, ...) \
w.type = malloc(sizeof(ev_ ## type)); \
if (w.type) { \
@@ -104,17 +132,12 @@ libev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
ev_child *child;
} w;
ev_tstamp interval;
- int events = EV_NONE;
w.watcher = NULL;
*flags |= VERTO_EV_FLAG_PERSIST;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
- if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
- events |= EV_READ;
- if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
- events |= EV_WRITE;
- setuptype(io, libev_callback, verto_get_fd(ev), events);
+ setuptype(io, libev_callback, verto_get_fd(ev), EV_NONE);
case VERTO_EV_TYPE_TIMEOUT:
interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0;
setuptype(timer, libev_callback, interval, interval);
@@ -129,8 +152,10 @@ libev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
break; /* Not supported */
}
- if (w.watcher)
+ if (w.watcher) {
w.watcher->data = (void*) ev;
+ libev_ctx_set_flags(ctx, ev, w.watcher);
+ }
return w.watcher;
}
diff --git a/src/util/verto/libverto.exports b/src/util/verto/libverto.exports
index 1e487744a3..098156fa2f 100644
--- a/src/util/verto/libverto.exports
+++ b/src/util/verto/libverto.exports
@@ -9,7 +9,9 @@ verto_default
verto_del
verto_fire
verto_free
+verto_get_ctx
verto_get_fd
+verto_get_fd_state
verto_get_flags
verto_get_interval
verto_get_private
@@ -22,6 +24,8 @@ verto_new
verto_reinitialize
verto_run
verto_run_once
+verto_set_allocator
verto_set_default
+verto_set_fd_state
verto_set_private
verto_set_proc_status
diff --git a/src/util/verto/module.c b/src/util/verto/module.c
index 8b81646596..d5977cbbc9 100644
--- a/src/util/verto/module.c
+++ b/src/util/verto/module.c
@@ -40,6 +40,51 @@ dllerror(void) {
LocalFree(msg);
return amsg;
}
+#elif defined(aix)
+#include "sys/ldr.h"
+
+struct Dl_info {
+ const char* dli_fname;
+};
+
+static int
+dladdr(void* s, Dl_info* i)
+{
+ static const size_t bufSize = 4096;
+ G__FastAllocString buf(bufSize);
+ char* pldi = buf;
+ int r;
+
+ r = loadquery(L_GETINFO, pldi, bufSize);
+ if (r == -1) {
+ i->dli_fname = NULL;
+ return 0;
+ }
+
+ for (ld_info* ldi = (ld_info*) buf;
+ ldi->ldinfo_next;
+ ldi += ldi->ldinfo_next) {
+ char* textBegin = (char*) ldi->ldinfo_textorg;
+ if (textBegin < s) {
+ char* textEnd = textBegin + ldi->ldinfo_textsize;
+ if (textEnd > s) {
+ i->dli_fname = ldi->ldinfo_filename;
+ return 1;
+ }
+ }
+ }
+
+ // First is main(), skip.
+ ld_info* ldi = (ld_info*) pldi;
+ while (ldi->ldinfo_next) {
+ pldi += ldi->ldinfo_next;
+ ldi = (ld_info*) pldi;
+
+ }
+
+ i->dli_fname = NULL;
+ return 0;
+}
#else
#define _GNU_SOURCE
#include <stdlib.h>
@@ -80,14 +125,14 @@ module_get_filename_for_symbol(void *addr, char **filename)
if (!GetModuleFileNameA(mod, tmp, MAX_PATH))
return 0;
-#else /* WIN32 */
+#else
const char *tmp;
Dl_info dlinfo;
if (!dladdr(addr, &dlinfo))
return 0;
tmp = dlinfo.dli_fname;
-#endif /* WIN32 */
+#endif
if (filename) {
*filename = strdup(tmp);
diff --git a/src/util/verto/verto-module.h b/src/util/verto/verto-module.h
index b0e7232b1e..4ef3b8af60 100644
--- a/src/util/verto/verto-module.h
+++ b/src/util/verto/verto-module.h
@@ -35,7 +35,7 @@ typedef void verto_mod_ctx;
typedef void verto_mod_ev;
#endif
-#define VERTO_MODULE_VERSION 2
+#define VERTO_MODULE_VERSION 3
#define VERTO_MODULE_TABLE(name) verto_module_table_ ## name
#define VERTO_MODULE(name, symb, types) \
static verto_ctx_funcs name ## _funcs = { \
@@ -46,6 +46,7 @@ typedef void verto_mod_ev;
name ## _ctx_run_once, \
name ## _ctx_break, \
name ## _ctx_reinitialize, \
+ name ## _ctx_set_flags, \
name ## _ctx_add, \
name ## _ctx_del \
}; \
@@ -75,6 +76,9 @@ typedef struct {
/* Required */ void (*ctx_run_once)(verto_mod_ctx *ctx);
/* Optional */ void (*ctx_break)(verto_mod_ctx *ctx);
/* Optional */ void (*ctx_reinitialize)(verto_mod_ctx *ctx);
+ /* Optional */ void (*ctx_set_flags)(verto_mod_ctx *ctx,
+ const verto_ev *ev,
+ verto_mod_ev *modev);
/* Required */ verto_mod_ev *(*ctx_add)(verto_mod_ctx *ctx,
const verto_ev *ev,
verto_ev_flag *flags);
@@ -166,4 +170,19 @@ verto_fire(verto_ev *ev);
void
verto_set_proc_status(verto_ev *ev, verto_proc_status status);
+/**
+ * Sets the state of the fd which caused this event to fire.
+ *
+ * This function does nothing if the verto_ev is not a io type.
+ *
+ * Only the flags VERTO_EV_FLAG_IO_(READ|WRITE|ERROR) are supported. All other
+ * flags are unset.
+ *
+ * @see verto_add_io()
+ * @param ev The verto_ev to set the state in.
+ * @param state The fd state.
+ */
+void
+verto_set_fd_state(verto_ev *ev, verto_ev_flag state);
+
#endif /* VERTO_MODULE_H_ */
diff --git a/src/util/verto/verto.c b/src/util/verto/verto.c
index af4172687d..44ea4373fc 100644
--- a/src/util/verto/verto.c
+++ b/src/util/verto/verto.c
@@ -22,7 +22,7 @@
* SOFTWARE.
*/
-#define _GNU_SOURCE /* For dladdr(), asprintf() */
+#define _GNU_SOURCE /* For asprintf() */
#include <stdio.h>
#include <stdlib.h>
@@ -45,6 +45,9 @@
#define _str(s) # s
#define __str(s) _str(s)
+/* Remove flags we can emulate */
+#define make_actual(flags) ((flags) & ~(VERTO_EV_FLAG_PERSIST|VERTO_EV_FLAG_IO_CLOSE_FD))
+
struct verto_ctx {
size_t ref;
verto_mod_ctx *ctx;
@@ -59,6 +62,11 @@ typedef struct {
verto_proc_status status;
} verto_child;
+typedef struct {
+ int fd;
+ verto_ev_flag state;
+} verto_io;
+
struct verto_ev {
verto_ev *next;
verto_ctx *ctx;
@@ -72,7 +80,7 @@ struct verto_ev {
size_t depth;
int deleted;
union {
- int fd;
+ verto_io io;
int signal;
time_t interval;
verto_child child;
@@ -88,7 +96,27 @@ struct module_record {
verto_ctx *defctx;
};
+
+#ifdef BUILTIN_MODULE
+#define _MODTABLE(n) verto_module_table_ ## n
+#define MODTABLE(n) _MODTABLE(n)
+/*
+ * This symbol can be used when embedding verto.c in a library along with a
+ * built-in private module, to preload the module instead of dynamically
+ * linking it in later. Define to verto_module_table_<modulename>.
+ */
+extern verto_module MODTABLE(BUILTIN_MODULE);
+static module_record builtin_record = {
+ NULL, &MODTABLE(BUILTIN_MODULE), NULL, "", NULL
+};
+static module_record *loaded_modules = &builtin_record;
+#else
static module_record *loaded_modules;
+#endif
+
+static void *(*resize_cb)(void *mem, size_t size);
+static int resize_cb_hierarchical;
+
#ifdef HAVE_PTHREAD
static pthread_mutex_t loaded_modules_mutex = PTHREAD_MUTEX_INITIALIZER;
#define mutex_lock(x) pthread_mutex_lock(x)
@@ -98,6 +126,16 @@ static pthread_mutex_t loaded_modules_mutex = PTHREAD_MUTEX_INITIALIZER;
#define mutex_unlock(x)
#endif
+#define vfree(mem) vresize(mem, 0)
+static void *
+vresize(void *mem, size_t size)
+{
+ if (!resize_cb)
+ resize_cb = &realloc;
+ return (*resize_cb)(mem, size);
+}
+
+#ifndef BUILTIN_MODULE
static int
int_vasprintf(char **strp, const char *fmt, va_list ap) {
va_list apc;
@@ -125,19 +163,6 @@ int_asprintf(char **strp, const char *fmt, ...) {
}
static char *
-int_get_table_name(const char *suffix)
-{
- char *tmp;
-
- tmp = malloc(strlen(suffix) + strlen(__str(VERTO_MODULE_TABLE())) + 1);
- if (tmp) {
- strcpy(tmp, __str(VERTO_MODULE_TABLE()));
- strcat(tmp, suffix);
- }
- return tmp;
-}
-
-static char *
int_get_table_name_from_filename(const char *filename)
{
char *bn = NULL, *tmp = NULL;
@@ -160,7 +185,8 @@ int_get_table_name_from_filename(const char *filename)
if (tmp) {
if (strchr(tmp+1, '.')) {
*strchr(tmp+1, '.') = '\0';
- tmp = int_get_table_name(tmp + 1);
+ if (int_asprintf(&tmp, "%s%s", __str(VERTO_MODULE_TABLE()), tmp + 1) < 0)
+ tmp = NULL;
} else
tmp = NULL;
}
@@ -225,13 +251,13 @@ do_load_file(const char *filename, int reqsym, verto_ev_type reqtypes,
mutex_unlock(&loaded_modules_mutex);
/* Create our module record */
- tmp = *record = malloc(sizeof(module_record));
+ tmp = *record = vresize(NULL, sizeof(module_record));
if (!tmp)
return 0;
memset(tmp, 0, sizeof(module_record));
tmp->filename = strdup(filename);
if (!tmp->filename) {
- free(tmp);
+ vfree(tmp);
return 0;
}
@@ -239,7 +265,7 @@ do_load_file(const char *filename, int reqsym, verto_ev_type reqtypes,
tblname = int_get_table_name_from_filename(filename);
if (!tblname) {
free(tblname);
- free(tmp);
+ vfree(tmp);
return 0;
}
@@ -252,7 +278,7 @@ do_load_file(const char *filename, int reqsym, verto_ev_type reqtypes,
free(error);
module_close(tmp->dll);
free(tblname);
- free(tmp);
+ vfree(tmp);
return 0;
}
@@ -311,14 +337,17 @@ do_load_dir(const char *dirname, const char *prefix, const char *suffix,
closedir(dir);
return *record != NULL;
}
+#endif
static int
load_module(const char *impl, verto_ev_type reqtypes, module_record **record)
{
int success = 0;
+#ifndef BUILTIN_MODULE
char *prefix = NULL;
char *suffix = NULL;
char *tmp = NULL;
+#endif
/* Check the cache */
mutex_lock(&loaded_modules_mutex);
@@ -341,6 +370,7 @@ load_module(const char *impl, verto_ev_type reqtypes, module_record **record)
}
mutex_unlock(&loaded_modules_mutex);
+#ifndef BUILTIN_MODULE
if (!module_get_filename_for_symbol(verto_convert_module, &prefix))
return 0;
@@ -394,14 +424,14 @@ load_module(const char *impl, verto_ev_type reqtypes, module_record **record)
success = do_load_dir(dname, prefix, suffix, 1, reqtypes,
record);
if (!success) {
-#ifdef DEFAULT_LIBRARY
+#ifdef DEFAULT_MODULE
/* Attempt to find the default module */
- success = load_module(DEFAULT_LIBRARY, reqtypes, record);
+ success = load_module(DEFAULT_MODULE, reqtypes, record);
if (!success)
-#endif /* DEFAULT_LIBRARY */
- /* Attempt to load any plugin (we're desperate) */
- success = do_load_dir(dname, prefix, suffix, 0,
- reqtypes, record);
+#endif /* DEFAULT_MODULE */
+ /* Attempt to load any plugin (we're desperate) */
+ success = do_load_dir(dname, prefix, suffix, 0,
+ reqtypes, record);
}
}
@@ -411,6 +441,7 @@ load_module(const char *impl, verto_ev_type reqtypes, module_record **record)
free(suffix);
free(prefix);
+#endif /* BUILTIN_MODULE */
return success;
}
@@ -423,7 +454,7 @@ make_ev(verto_ctx *ctx, verto_callback *callback,
if (!ctx || !callback)
return NULL;
- ev = malloc(sizeof(verto_ev));
+ ev = vresize(NULL, sizeof(verto_ev));
if (ev) {
memset(ev, 0, sizeof(verto_ev));
ev->ctx = ctx;
@@ -502,6 +533,17 @@ verto_set_default(const char *impl, verto_ev_type reqtypes)
return load_module(impl, reqtypes, &mr);
}
+int
+verto_set_allocator(void *(*resize)(void *mem, size_t size),
+ int hierarchical)
+{
+ if (resize_cb || !resize)
+ return 0;
+ resize_cb = resize;
+ resize_cb_hierarchical = hierarchical;
+ return 1;
+}
+
void
verto_free(verto_ctx *ctx)
{
@@ -520,7 +562,7 @@ verto_free(verto_ctx *ctx)
if (!ctx->deflt || !ctx->module->funcs->ctx_default)
ctx->module->funcs->ctx_free(ctx->ctx);
- free(ctx);
+ vfree(ctx);
}
void
@@ -583,7 +625,7 @@ verto_reinitialize(verto_ctx *ctx)
/* Recreate events that were marked forkable */
for (tmp = ctx->events; tmp; tmp = tmp->next) {
- tmp->actual = tmp->flags;
+ tmp->actual = make_actual(tmp->flags);
tmp->ev = ctx->module->funcs->ctx_add(ctx->ctx, tmp, &tmp->actual);
if (!tmp->ev)
error = 0;
@@ -596,10 +638,10 @@ verto_reinitialize(verto_ctx *ctx)
ev = make_ev(ctx, callback, type, flags); \
if (ev) { \
set; \
- ev->actual = ev->flags; \
+ ev->actual = make_actual(ev->flags); \
ev->ev = ctx->module->funcs->ctx_add(ctx->ctx, ev, &ev->actual); \
if (!ev->ev) { \
- free(ev); \
+ vfree(ev); \
return NULL; \
} \
push_ev(ctx, ev); \
@@ -614,7 +656,7 @@ verto_add_io(verto_ctx *ctx, verto_ev_flag flags,
if (fd < 0 || !(flags & (VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_IO_WRITE)))
return NULL;
- doadd(ev, ev->option.fd = fd, VERTO_EV_TYPE_IO);
+ doadd(ev, ev->option.io.fd = fd, VERTO_EV_TYPE_IO);
return ev;
}
@@ -704,14 +746,43 @@ verto_get_flags(const verto_ev *ev)
return ev->flags;
}
+void
+verto_set_flags(verto_ev *ev, verto_ev_flag flags)
+{
+ if (!ev)
+ return;
+
+ ev->flags &= ~_VERTO_EV_FLAG_MUTABLE_MASK;
+ ev->flags |= flags & _VERTO_EV_FLAG_MUTABLE_MASK;
+
+ /* If setting flags isn't supported, just rebuild the event */
+ if (!ev->ctx->module->funcs->ctx_set_flags) {
+ ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev);
+ ev->actual = make_actual(ev->flags);
+ ev->ev = ev->ctx->module->funcs->ctx_add(ev->ctx->ctx, ev, &ev->actual);
+ assert(ev->ev); /* Here is the main reason why modules should */
+ return; /* implement set_flags(): we cannot fail gracefully. */
+ }
+
+ ev->actual &= ~_VERTO_EV_FLAG_MUTABLE_MASK;
+ ev->actual |= flags & _VERTO_EV_FLAG_MUTABLE_MASK;
+ ev->ctx->module->funcs->ctx_set_flags(ev->ctx->ctx, ev, ev->ev);
+}
+
int
verto_get_fd(const verto_ev *ev)
{
if (ev && (ev->type == VERTO_EV_TYPE_IO))
- return ev->option.fd;
+ return ev->option.io.fd;
return -1;
}
+verto_ev_flag
+verto_get_fd_state(const verto_ev *ev)
+{
+ return ev->option.io.state;
+}
+
time_t
verto_get_interval(const verto_ev *ev)
{
@@ -741,6 +812,12 @@ verto_get_proc_status(const verto_ev *ev)
return ev->option.child.status;
}
+verto_ctx *
+verto_get_ctx(const verto_ev *ev)
+{
+ return ev->ctx;
+}
+
void
verto_del(verto_ev *ev)
{
@@ -760,7 +837,13 @@ verto_del(verto_ev *ev)
ev->onfree(ev->ctx, ev);
ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev);
remove_ev(&(ev->ctx->events), ev);
- free(ev);
+
+ if ((ev->type == VERTO_EV_TYPE_IO) &&
+ (ev->flags & VERTO_EV_FLAG_IO_CLOSE_FD) &&
+ !(ev->actual & VERTO_EV_FLAG_IO_CLOSE_FD))
+ close(ev->option.io.fd);
+
+ vfree(ev);
}
verto_ev_type
@@ -806,7 +889,7 @@ verto_convert_module(const verto_module *module, int deflt, verto_mod_ctx *mctx)
goto error;
}
- ctx = malloc(sizeof(verto_ctx));
+ ctx = vresize(NULL, sizeof(verto_ctx));
if (!ctx)
goto error;
memset(ctx, 0, sizeof(verto_ctx));
@@ -836,9 +919,9 @@ verto_convert_module(const verto_module *module, int deflt, verto_mod_ctx *mctx)
}
mutex_unlock(&loaded_modules_mutex);
- *tmp = malloc(sizeof(module_record));
+ *tmp = vresize(NULL, sizeof(module_record));
if (!*tmp) {
- free(ctx);
+ vfree(ctx);
goto error;
}
@@ -867,12 +950,19 @@ verto_fire(verto_ev *ev)
if (ev->depth == 0) {
if (!(ev->flags & VERTO_EV_FLAG_PERSIST) || ev->deleted)
verto_del(ev);
- else if (!ev->actual & VERTO_EV_FLAG_PERSIST) {
- ev->actual = ev->flags;
- priv = ev->ctx->module->funcs->ctx_add(ev->ctx->ctx, ev, &ev->actual);
- assert(priv); /* TODO: create an error callback */
- ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev);
- ev->ev = priv;
+ else {
+ if (!(ev->actual & VERTO_EV_FLAG_PERSIST)) {
+ ev->actual = make_actual(ev->flags);
+ priv = ev->ctx->module->funcs->ctx_add(ev->ctx->ctx, ev, &ev->actual);
+ assert(priv); /* TODO: create an error callback */
+ ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev);
+ ev->ev = priv;
+ }
+
+ if (ev->type == VERTO_EV_TYPE_IO)
+ ev->option.io.state = VERTO_EV_FLAG_NONE;
+ if (ev->type == VERTO_EV_TYPE_CHILD)
+ ev->option.child.status = 0;
}
}
}
@@ -883,3 +973,19 @@ verto_set_proc_status(verto_ev *ev, verto_proc_status status)
if (ev && ev->type == VERTO_EV_TYPE_CHILD)
ev->option.child.status = status;
}
+
+void
+verto_set_fd_state(verto_ev *ev, verto_ev_flag state)
+{
+ /* Filter out only the io flags */
+ state = state & (VERTO_EV_FLAG_IO_READ |
+ VERTO_EV_FLAG_IO_WRITE |
+ VERTO_EV_FLAG_IO_ERROR);
+
+ /* Don't report read/write if the socket is closed */
+ if (state & VERTO_EV_FLAG_IO_ERROR)
+ state = VERTO_EV_FLAG_IO_ERROR;
+
+ if (ev && ev->type == VERTO_EV_TYPE_IO)
+ ev->option.io.state = state;
+}
diff --git a/src/util/verto/verto.h b/src/util/verto/verto.h
index 23d9a20969..5540367717 100644
--- a/src/util/verto/verto.h
+++ b/src/util/verto/verto.h
@@ -39,6 +39,11 @@ typedef int verto_proc_status;
#define VERTO_SIG_IGN ((verto_callback *) 1)
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
typedef struct verto_ctx verto_ctx;
typedef struct verto_ev verto_ev;
@@ -59,8 +64,15 @@ typedef enum {
VERTO_EV_FLAG_PRIORITY_HIGH = 1 << 3,
VERTO_EV_FLAG_IO_READ = 1 << 4,
VERTO_EV_FLAG_IO_WRITE = 1 << 5,
+ VERTO_EV_FLAG_IO_ERROR = 1 << 7,
+ VERTO_EV_FLAG_IO_CLOSE_FD = 1 << 8,
VERTO_EV_FLAG_REINITIABLE = 1 << 6,
- _VERTO_EV_FLAG_MAX = VERTO_EV_FLAG_REINITIABLE
+ _VERTO_EV_FLAG_MUTABLE_MASK = VERTO_EV_FLAG_PRIORITY_LOW
+ | VERTO_EV_FLAG_PRIORITY_MEDIUM
+ | VERTO_EV_FLAG_PRIORITY_HIGH
+ | VERTO_EV_FLAG_IO_READ
+ | VERTO_EV_FLAG_IO_WRITE,
+ _VERTO_EV_FLAG_MAX = VERTO_EV_FLAG_IO_CLOSE_FD
} verto_ev_flag;
typedef void (verto_callback)(verto_ctx *ctx, verto_ev *ev);
@@ -171,6 +183,25 @@ int
verto_set_default(const char *impl, verto_ev_type reqtypes);
/**
+ * Sets the allocator to use for verto_ctx and verto_ev objects.
+ *
+ * If you plan to set the allocator, you MUST call this function before any
+ * other verto_*() calls.
+ *
+ * @see verto_new()
+ * @see verto_default()
+ * @see verto_add_io()
+ * @see verto_add_timeout()
+ * @see verto_add_idle()
+ * @see verto_add_signal()
+ * @see verto_add_child()
+ * @param resize The allocator to use (behaves like realloc())
+ * @param hierarchical Zero if the allocator is not hierarchical
+ */
+int
+verto_set_allocator(void *(*resize)(void *mem, size_t size), int hierarchical);
+
+/**
* Frees a verto_ctx.
*
* When called on a default verto_ctx, the reference will be freed but the
@@ -237,6 +268,8 @@ verto_reinitialize(verto_ctx *ctx);
* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically
* after its execution. In either case, you may call verto_del() at any time
* to prevent the event from executing.
+ * If VERTO_EV_FLAG_IO_CLOSE_FD is provided the passed in fd is automatically
+ * closed when the event is freed with verto_del()
*
* NOTE: On Windows, the underlying select() only works with sockets. As such,
* any attempt to add a non-socket io event on Windows will produce undefined
@@ -400,6 +433,7 @@ verto_get_type(const verto_ev *ev);
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
+ * @see verto_set_flags()
* @param ev The verto_ev
* @return The verto_ev type
*/
@@ -407,6 +441,24 @@ verto_ev_flag
verto_get_flags(const verto_ev *ev);
/**
+ * Sets the flags associated with the given verto_ev.
+ *
+ * See _VERTO_EV_FLAG_MUTABLE_MASK for the flags that can be changed
+ * with this function. All others will be ignored.
+ *
+ * @see verto_add_io()
+ * @see verto_add_timeout()
+ * @see verto_add_idle()
+ * @see verto_add_signal()
+ * @see verto_add_child()
+ * @see verto_get_flags()
+ * @param ev The verto_ev
+ * @param flags The flags for the event
+ */
+void
+verto_set_flags(verto_ev *ev, verto_ev_flag flags);
+
+/**
* Gets the file descriptor associated with a read/write verto_ev.
*
* @see verto_add_io()
@@ -417,6 +469,16 @@ int
verto_get_fd(const verto_ev *ev);
/**
+ * Gets the file descriptor state from when the event fires.
+ *
+ * @see verto_add_io()
+ * @param ev The verto_ev to retrieve the fd state from.
+ * @return The fd state.
+ */
+verto_ev_flag
+verto_get_fd_state(const verto_ev *ev);
+
+/**
* Gets the interval associated with a timeout verto_ev.
*
* @see verto_add_timeout()
@@ -457,6 +519,17 @@ verto_proc_status
verto_get_proc_status(const verto_ev *ev);
/**
+ * Gets the verto_ctx associated with a verto_ev.
+ *
+ * This is a borrowed reference, don't attempt to free it!
+ *
+ * @param ev The verto_ev to retrieve the verto_ctx from.
+ * @return The verto_ctx.
+ */
+verto_ctx *
+verto_get_ctx(const verto_ev *ev);
+
+/**
* Removes an event from from the event context and frees it.
*
* The event and its contents cannot be used after this call.
@@ -480,4 +553,7 @@ verto_del(verto_ev *ev);
verto_ev_type
verto_get_supported_types(verto_ctx *ctx);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
#endif /* VERTO_H_ */