diff options
Diffstat (limited to 'src/util/verto/verto.c')
-rw-r--r-- | src/util/verto/verto.c | 131 |
1 files changed, 95 insertions, 36 deletions
diff --git a/src/util/verto/verto.c b/src/util/verto/verto.c index 44ea4373fcf3..71eaffa080de 100644 --- a/src/util/verto/verto.c +++ b/src/util/verto/verto.c @@ -22,8 +22,6 @@ * SOFTWARE. */ -#define _GNU_SOURCE /* For asprintf() */ - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -45,6 +43,8 @@ #define _str(s) # s #define __str(s) _str(s) +#define MUTABLE(flags) (flags & _VERTO_EV_FLAG_MUTABLE_MASK) + /* Remove flags we can emulate */ #define make_actual(flags) ((flags) & ~(VERTO_EV_FLAG_PERSIST|VERTO_EV_FLAG_IO_CLOSE_FD)) @@ -103,7 +103,7 @@ struct module_record { /* * 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>. + * linking it in later. Define to <modulename>. */ extern verto_module MODTABLE(BUILTIN_MODULE); static module_record builtin_record = { @@ -119,12 +119,43 @@ 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) -#define mutex_unlock(x) pthread_mutex_unlock(x) -#else + +#ifndef NDEBUG +#define mutex_lock(x) { \ + int c = pthread_mutex_lock(x); \ + if (c != 0) { \ + fprintf(stderr, "pthread_mutex_lock returned %d (%s) in %s", \ + c, strerror(c), __FUNCTION__); \ + } \ + assert(c == 0); \ + } +#define mutex_unlock(x) { \ + int c = pthread_mutex_unlock(x); \ + if (c != 0) { \ + fprintf(stderr, "pthread_mutex_unlock returned %d (%s) in %s", \ + c, strerror(c), __FUNCTION__); \ + } \ + assert(c == 0); \ + } +#define mutex_destroy(x) { \ + int c = pthread_mutex_destroy(x); \ + if (c != 0) { \ + fprintf(stderr, "pthread_mutex_destroy returned %d (%s) in %s", \ + c, strerror(c), __FUNCTION__); \ + } \ + assert(c == 0); \ + } +#else /* NDEBUG */ +#define mutex_lock pthread_mutex_lock +#define mutex_unlock pthread_mutex_unlock +#define mutex_destroy pthread_mutex_destroy +#endif /* NDEBUG */ + +#else /* HAVE_PTHREAD */ #define mutex_lock(x) #define mutex_unlock(x) -#endif +#define mutex_destroy(x) +#endif /* HAVE_PTHREAD */ #define vfree(mem) vresize(mem, 0) static void * @@ -132,34 +163,35 @@ vresize(void *mem, size_t size) { if (!resize_cb) resize_cb = &realloc; + if (size == 0 && resize_cb == &realloc) { + /* Avoid memleak as realloc(X, 0) can return a free-able pointer. */ + free(mem); + return NULL; + } return (*resize_cb)(mem, size); } #ifndef BUILTIN_MODULE -static int -int_vasprintf(char **strp, const char *fmt, va_list ap) { - va_list apc; - int size = 0; - - va_copy(apc, ap); - size = vsnprintf(NULL, 0, fmt, apc); - va_end(apc); +static char * +string_aconcat(const char *first, const char *second, const char *third) { + char *ret; + size_t len; - if (size <= 0 || !(*strp = malloc(size + 1))) - return -1; + len = strlen(first) + strlen(second); + if (third) + len += strlen(third); - return vsnprintf(*strp, size + 1, fmt, ap); -} + ret = malloc(len + 1); + if (!ret) + return NULL; -static int -int_asprintf(char **strp, const char *fmt, ...) { - va_list ap; - int size = 0; + strncpy(ret, first, strlen(first)); + strncpy(ret + strlen(first), second, strlen(second)); + if (third) + strncpy(ret + strlen(first) + strlen(second), third, strlen(third)); - va_start(ap, fmt); - size = int_vasprintf(strp, fmt, ap); - va_end(ap); - return size; + ret[len] = '\0'; + return ret; } static char * @@ -185,8 +217,7 @@ int_get_table_name_from_filename(const char *filename) if (tmp) { if (strchr(tmp+1, '.')) { *strchr(tmp+1, '.') = '\0'; - if (int_asprintf(&tmp, "%s%s", __str(VERTO_MODULE_TABLE()), tmp + 1) < 0) - tmp = NULL; + tmp = string_aconcat(__str(VERTO_MODULE_TABLE()), tmp + 1, NULL); } else tmp = NULL; } @@ -217,7 +248,7 @@ shouldload(void *symb, void *misc, char **err) if (table->symb && data->reqsym && !module_symbol_is_present(NULL, table->symb)) { if (err) - int_asprintf(err, "Symbol not found: %s!", table->symb); + *err = string_aconcat("Symbol not found: ", table->symb, "!"); return 0; } @@ -265,6 +296,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->filename); vfree(tmp); return 0; } @@ -278,6 +310,7 @@ do_load_file(const char *filename, int reqsym, verto_ev_type reqtypes, free(error); module_close(tmp->dll); free(tblname); + free(tmp->filename); vfree(tmp); return 0; } @@ -324,7 +357,8 @@ do_load_dir(const char *dirname, const char *prefix, const char *suffix, if (flen < slen || strcmp(ent->d_name + flen - slen, suffix)) continue; - if (int_asprintf(&tmp, "%s/%s", dirname, ent->d_name) < 0) + tmp = string_aconcat(dirname, "/", ent->d_name); + if (!tmp) continue; success = do_load_file(tmp, reqsym, reqtypes, record); @@ -401,8 +435,8 @@ load_module(const char *impl, verto_ev_type reqtypes, module_record **record) success = do_load_file(impl, 0, reqtypes, record); if (!success) { /* Try to do a load by the name */ - tmp = NULL; - if (int_asprintf(&tmp, "%s%s%s", prefix, impl, suffix) > 0) { + tmp = string_aconcat(prefix, impl, suffix); + if (tmp) { success = do_load_file(tmp, 0, reqtypes, record); free(tmp); } @@ -494,6 +528,8 @@ remove_ev(verto_ev **origin, verto_ev *item) static void signal_ignore(verto_ctx *ctx, verto_ev *ev) { + (void) ctx; + (void) ev; } verto_ctx * @@ -566,6 +602,25 @@ verto_free(verto_ctx *ctx) } void +verto_cleanup(void) +{ + module_record *record; + + mutex_lock(&loaded_modules_mutex); + + for (record = loaded_modules; record; record = record->next) { + module_close(record->dll); + free(record->filename); + } + + vfree(loaded_modules); + loaded_modules = NULL; + + mutex_unlock(&loaded_modules_mutex); + mutex_destroy(&loaded_modules_mutex); +} + +void verto_run(verto_ctx *ctx) { if (!ctx) @@ -752,8 +807,12 @@ verto_set_flags(verto_ev *ev, verto_ev_flag flags) if (!ev) return; + /* No modification is needed, so do nothing. */ + if (MUTABLE(ev->flags) == MUTABLE(flags)) + return; + ev->flags &= ~_VERTO_EV_FLAG_MUTABLE_MASK; - ev->flags |= flags & _VERTO_EV_FLAG_MUTABLE_MASK; + ev->flags |= MUTABLE(flags); /* If setting flags isn't supported, just rebuild the event */ if (!ev->ctx->module->funcs->ctx_set_flags) { @@ -765,7 +824,7 @@ verto_set_flags(verto_ev *ev, verto_ev_flag flags) } ev->actual &= ~_VERTO_EV_FLAG_MUTABLE_MASK; - ev->actual |= flags & _VERTO_EV_FLAG_MUTABLE_MASK; + ev->actual |= MUTABLE(flags); ev->ctx->module->funcs->ctx_set_flags(ev->ctx->ctx, ev, ev->ev); } @@ -861,7 +920,7 @@ verto_convert_module(const verto_module *module, int deflt, verto_mod_ctx *mctx) module_record *mr; if (!module) - goto error; + return NULL; if (deflt) { mutex_lock(&loaded_modules_mutex); |