diff options
Diffstat (limited to 'src/libmowgli/module')
-rw-r--r-- | src/libmowgli/module/Makefile | 2 | ||||
-rw-r--r-- | src/libmowgli/module/interface.c | 73 | ||||
-rw-r--r-- | src/libmowgli/module/loader_posix.c | 29 | ||||
-rw-r--r-- | src/libmowgli/module/loader_win32.c | 21 | ||||
-rw-r--r-- | src/libmowgli/module/module.h | 17 |
5 files changed, 117 insertions, 25 deletions
diff --git a/src/libmowgli/module/Makefile b/src/libmowgli/module/Makefile index 702ed7c..19d885a 100644 --- a/src/libmowgli/module/Makefile +++ b/src/libmowgli/module/Makefile @@ -3,7 +3,7 @@ include ../../../extra.mk STATIC_PIC_LIB_NOINST = ${LIBMOWGLI_SHARED_MODULE} STATIC_LIB_NOINST = ${LIBMOWGLI_STATIC_MODULE} -SRCS = loader_${LIBMOWGLI_OS}.c +SRCS = interface.c loader_${LIBMOWGLI_OS}.c INCLUDES = module.h diff --git a/src/libmowgli/module/interface.c b/src/libmowgli/module/interface.c new file mode 100644 index 0000000..a552605 --- /dev/null +++ b/src/libmowgli/module/interface.c @@ -0,0 +1,73 @@ +/* + * libmowgli: A collection of useful routines for programming. + * module.h: Loadable modules. + * + * Copyright (c) 2007, 2014 William Pitcock <william@dereferenced.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#include "mowgli.h" + +static mowgli_patricia_t *mowgli_interface_dict = NULL; +static mowgli_mutex_t mowgli_interface_lock; + +void +mowgli_interface_bootstrap(void) +{ + mowgli_interface_dict = mowgli_patricia_create(NULL); + mowgli_mutex_init(&mowgli_interface_lock); +} + +void +mowgli_interface_register(mowgli_interface_t *iface) +{ + mowgli_interface_base_t *base_iface = iface; + + mowgli_mutex_lock(&mowgli_interface_lock); + mowgli_patricia_add(mowgli_interface_dict, base_iface->id, iface); + mowgli_mutex_unlock(&mowgli_interface_lock); +} + +void +mowgli_interface_unregister(mowgli_interface_t *iface) +{ + mowgli_interface_base_t *base_iface = iface; + + mowgli_mutex_lock(&mowgli_interface_lock); + mowgli_patricia_delete(mowgli_interface_dict, base_iface->id); + mowgli_mutex_unlock(&mowgli_interface_lock); +} + +mowgli_interface_t * +mowgli_interface_get(const char *id, uint32_t abirev) +{ + mowgli_interface_base_t *base_iface; + + mowgli_mutex_lock(&mowgli_interface_lock); + + base_iface = mowgli_patricia_retrieve(mowgli_interface_dict, id); + if (base_iface->abirev != abirev) + { + mowgli_log("requested interface %s, abi mismatch %d != %d", id, abirev, base_iface->abirev); + base_iface = NULL; + } + + mowgli_mutex_unlock(&mowgli_interface_lock); + + return base_iface; +} diff --git a/src/libmowgli/module/loader_posix.c b/src/libmowgli/module/loader_posix.c index f15c38a..d4114e7 100644 --- a/src/libmowgli/module/loader_posix.c +++ b/src/libmowgli/module/loader_posix.c @@ -30,22 +30,25 @@ #endif #ifndef RTLD_LOCAL -#define RTLD_LOCAL 0 +# define RTLD_LOCAL 0 #endif -mowgli_module_t mowgli_module_open(const char *path) +mowgli_module_t +mowgli_module_open(const char *path) { void *handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); - /* make sure we have something. make this an assertion so that - * there is feedback if something happens. (poor programming practice). - */ - return_val_if_fail(handle != NULL, NULL); + if (handle == NULL) + { + mowgli_log("Failed to open %s: %s", path, dlerror()); + return NULL; + } return handle; } -void * mowgli_module_symbol(mowgli_module_t module, const char *symbol) +void * +mowgli_module_symbol(mowgli_module_t module, const char *symbol) { void *handle; @@ -53,15 +56,17 @@ void * mowgli_module_symbol(mowgli_module_t module, const char *symbol) handle = dlsym(module, symbol); - /* make sure we have something. make this an assertion so that - * there is feedback if something happens. (poor programming practice). - */ - return_val_if_fail(handle != NULL, NULL); + if (handle == NULL) + { + mowgli_log("Failed to find symbol %s: %s", symbol, dlerror()); + return NULL; + } return handle; } -void mowgli_module_close(mowgli_module_t module) +void +mowgli_module_close(mowgli_module_t module) { return_if_fail(module != NULL); diff --git a/src/libmowgli/module/loader_win32.c b/src/libmowgli/module/loader_win32.c index f42a742..70cd1b6 100644 --- a/src/libmowgli/module/loader_win32.c +++ b/src/libmowgli/module/loader_win32.c @@ -23,30 +23,32 @@ #include "mowgli.h" -#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN #include <windows.h> -mowgli_module_t mowgli_module_open(const char *path) +mowgli_module_t +mowgli_module_open(const char *path) { HANDLE handle = LoadLibraryA(path); - /* make sure we have something. make this an assertion so that + /* make sure we have something. make this an assertion so that * there is feedback if something happens. (poor programming practice). */ return_val_if_fail(handle != NULL, NULL); - return (mowgli_module_t)handle; + return (mowgli_module_t) handle; } -void * mowgli_module_symbol(mowgli_module_t module, const char *symbol) +void * +mowgli_module_symbol(mowgli_module_t module, const char *symbol) { void *handle; return_val_if_fail(module != NULL, NULL); - handle = GetProcAddress((HANDLE)module, symbol); + handle = GetProcAddress((HANDLE) module, symbol); - /* make sure we have something. make this an assertion so that + /* make sure we have something. make this an assertion so that * there is feedback if something happens. (poor programming practice). */ return_val_if_fail(handle != NULL, NULL); @@ -54,9 +56,10 @@ void * mowgli_module_symbol(mowgli_module_t module, const char *symbol) return handle; } -void mowgli_module_close(mowgli_module_t module) +void +mowgli_module_close(mowgli_module_t module) { return_if_fail(module != NULL); - FreeLibrary((HANDLE)module); + FreeLibrary((HANDLE) module); } diff --git a/src/libmowgli/module/module.h b/src/libmowgli/module/module.h index 54fc344..214fd51 100644 --- a/src/libmowgli/module/module.h +++ b/src/libmowgli/module/module.h @@ -2,7 +2,7 @@ * libmowgli: A collection of useful routines for programming. * module.h: Loadable modules. * - * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk> + * Copyright (c) 2007, 2014 William Pitcock <william@dereferenced.org> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,10 +24,21 @@ #ifndef __MOWGLI_MODULE_H__ #define __MOWGLI_MODULE_H__ -typedef void * mowgli_module_t; +typedef void *mowgli_module_t; extern mowgli_module_t mowgli_module_open(const char *path); -extern void * mowgli_module_symbol(mowgli_module_t module, const char *symbol); +extern void *mowgli_module_symbol(mowgli_module_t module, const char *symbol); extern void mowgli_module_close(mowgli_module_t module); +typedef void mowgli_interface_t; + +typedef struct { + const char *id; + uint32_t abirev; +} mowgli_interface_base_t; + +extern void mowgli_interface_register(mowgli_interface_t *iface); +extern void mowgli_interface_unregister(mowgli_interface_t *iface); +extern mowgli_interface_t *mowgli_interface_get(const char *id, uint32_t abirev); + #endif |