summaryrefslogtreecommitdiff
path: root/src/libmowgli/module
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmowgli/module')
-rw-r--r--src/libmowgli/module/Makefile2
-rw-r--r--src/libmowgli/module/interface.c73
-rw-r--r--src/libmowgli/module/loader_posix.c29
-rw-r--r--src/libmowgli/module/loader_win32.c21
-rw-r--r--src/libmowgli/module/module.h17
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