|
From: <cli...@li...> - 2007-05-15 20:58:39
|
Revision: 50
http://cligg.svn.sourceforge.net/cligg/?rev=50&view=rev
Author: sithhell
Date: 2007-05-15 13:58:37 -0700 (Tue, 15 May 2007)
Log Message:
-----------
implemented our module handler, which registers two events: load_module, unload_module\n added constructor and destructor for the modules see src/lib/cligg_module.h
Modified Paths:
--------------
src/bin/CMakeLists.txt
src/bin/cligg.c
src/bin/cligg_mainloop.c
src/lib/cligg_event.c
src/lib/cligg_event.h
src/lib/cligg_hashmap.h
src/lib/cligg_list.c
src/lib/cligg_list.h
src/lib/cligg_module.c
src/lib/cligg_module.h
Added Paths:
-----------
src/bin/cligg_modulehandler.c
src/bin/cligg_modulehandler.h
Modified: src/bin/CMakeLists.txt
===================================================================
--- src/bin/CMakeLists.txt 2007-05-14 21:47:41 UTC (rev 49)
+++ src/bin/CMakeLists.txt 2007-05-15 20:58:37 UTC (rev 50)
@@ -1,6 +1,7 @@
add_library(cligg_mainloop STATIC cligg_mainloop.c)
add_library(cligg_eventhandler STATIC cligg_eventhandler.c)
+add_library(cligg_modulehandler STATIC cligg_modulehandler.c)
add_executable(cligg cligg.c)
-target_link_libraries(cligg cligglib cligg_mainloop cligg_eventhandler pthread)
+target_link_libraries(cligg cligglib cligg_mainloop cligg_eventhandler cligg_modulehandler pthread dl)
add_executable(tree_test test.c)
target_link_libraries(tree_test cligglib)
Modified: src/bin/cligg.c
===================================================================
--- src/bin/cligg.c 2007-05-14 21:47:41 UTC (rev 49)
+++ src/bin/cligg.c 2007-05-15 20:58:37 UTC (rev 50)
@@ -12,6 +12,7 @@
#include <cligg_event.h>
#include <cligg_eventhandler.h>
#include <cligg_mainloop.h>
+#include <cligg_modulehandler.h>
/**
* @file cligg.c
@@ -37,15 +38,18 @@
{
int ret;
+#ifndef _POSIX_THREADS
+ fprintf(stderr, "Your Platform is not supported at the moment!\n");
+ exit(EXIT_FAILURE);
+#endif
+
/* initialisition */
ret = cligg_init_handler();
if(!ret)
exit(EXIT_FAILURE);
-#ifndef _POSIX_THREADS
- fprintf(stderr, "Your Platform is not supported at the moment!\n");
- exit(EXIT_FAILURE);
-#endif
+ /* init module system */
+ ret = cligg_init_modulehandler();
/* TODO load the config */
Modified: src/bin/cligg_mainloop.c
===================================================================
--- src/bin/cligg_mainloop.c 2007-05-14 21:47:41 UTC (rev 49)
+++ src/bin/cligg_mainloop.c 2007-05-15 20:58:37 UTC (rev 50)
@@ -54,7 +54,8 @@
if(cb == NULL) continue;
- cb(new->data);
+ if(!cb(new->data))
+ fprintf(stderr, "Event callback failed!\n");
}
return (void *)EXIT_SUCCESS;
Added: src/bin/cligg_modulehandler.c
===================================================================
--- src/bin/cligg_modulehandler.c (rev 0)
+++ src/bin/cligg_modulehandler.c 2007-05-15 20:58:37 UTC (rev 50)
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <dlfcn.h>
+#include <cligg.h>
+#include <cligglib.h>
+#include <cligg_list.h>
+#include <cligg_module.h>
+#include <cligg_eventhandler.h>
+#include <cligg_modulehandler.h>
+
+static int cmp(void *a, void *b);
+static int module_reg_event_cb(void *data);
+static int module_unreg_event_cb(void *data);
+
+static pthread_mutex_t module_lock = PTHREAD_MUTEX_INITIALIZER;
+static cligg_list *module_list;
+
+int
+cligg_init_modulehandler(void)
+{
+ module_list = cligg_list_new(cligg_module_del);
+ if(module_list == NULL)
+ return FALSE;
+
+ if(!cligg_register_event("load_module", module_reg_event_cb)) {
+ free(module_list);
+ return FALSE;
+ }
+ if(!cligg_register_event("unload_module", module_unreg_event_cb)) {
+ free(module_list);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int
+cligg_del_modulehandler(void)
+{
+ cligg_module *tmp;
+ while((tmp = cligg_list_element_get_first(module_list))) {
+ cligg_unregister_module(tmp);
+ }
+ cligg_list_del(module_list);
+
+ return TRUE;
+}
+
+int cligg_register_module(char *path)
+{
+ cligg_module *new = cligg_module_new(path);
+ if(new == NULL) {
+ perror("Error loading module");
+ return FALSE;
+ }
+
+ new->handle = dlopen(path, RTLD_LAZY);
+ if(!new->handle) {
+ fprintf(stderr, "Error loading module: %s\n", dlerror());
+ return FALSE;
+ }
+
+ if(pthread_mutex_lock(&module_lock) != 0) {
+ fprintf(stderr, "Couldn't obtain module lock!\n");
+ cligg_module_del(new);
+ return FALSE;
+ }
+
+ if(!cligg_list_element_append(module_list, new)) {
+ perror("Error loading module");
+ return FALSE;
+ }
+ if(pthread_mutex_unlock(&module_lock) != 0) {
+ fprintf(stderr, "Couldn't unlock module lock!\n");
+ cligg_module_del(new);
+ return FALSE;
+ }
+
+
+ dlerror(); /* clear any existing errors */
+ return TRUE;
+}
+
+int cligg_unregister_module(cligg_module *module)
+{
+ cligg_module *tmp;
+ int ret = TRUE;
+
+ if(pthread_mutex_lock(&module_lock) != 0) {
+ fprintf(stderr, "Couldn't obtain module lock!\n");
+ cligg_module_del(tmp);
+ return FALSE;
+ }
+
+ if(cligg_list_element_find(module_list, cmp, module) == -1) {
+ fprintf(stderr, "Couldn't delete module: Not found!\n");
+ ret = FALSE;
+ goto jump;
+ }
+
+ tmp = (cligg_module *)module_list->current->data;
+
+ dlclose(tmp->handle);
+
+ cligg_list_element_del_current(module_list);
+
+ if(pthread_mutex_unlock(&module_lock) != 0) {
+ fprintf(stderr, "Couldn't unlock module lock!\n");
+ cligg_module_del(tmp);
+ return FALSE;
+ }
+jump:
+ return ret;
+}
+
+static int cmp(void *a, void *b)
+{
+ return strcmp(((cligg_module *)a)->path, ((cligg_module *)b)->path);
+}
+
+static int module_reg_event_cb(void *data)
+{
+ return cligg_register_module((char *)data);
+}
+
+static int module_unreg_event_cb(void *data)
+{
+ return cligg_unregister_module((cligg_module *)data);
+}
Added: src/bin/cligg_modulehandler.h
===================================================================
--- src/bin/cligg_modulehandler.h (rev 0)
+++ src/bin/cligg_modulehandler.h 2007-05-15 20:58:37 UTC (rev 50)
@@ -0,0 +1,12 @@
+#ifndef CLIGG_MODULEHANDLER_H
+#define CLIGG_MODULEHANDLER_H
+
+#include <cligg_module.h>
+
+int cligg_init_modulehandler(void);
+int cligg_del_modulehandler(void);
+
+int cligg_register_module(char *);
+int cligg_unregister_module(cligg_module *);
+
+#endif
Modified: src/lib/cligg_event.c
===================================================================
--- src/lib/cligg_event.c 2007-05-14 21:47:41 UTC (rev 49)
+++ src/lib/cligg_event.c 2007-05-15 20:58:37 UTC (rev 50)
@@ -15,7 +15,7 @@
if(new->name == NULL)
return NULL;
- strcpy(name, new->name);
+ strcpy(new->name, name);
new->data = data;
@@ -41,7 +41,7 @@
if(new->name == NULL)
return NULL;
- strcpy(name, new->name);
+ strcpy(new->name, name);
new->event_cb = event_cb;
Modified: src/lib/cligg_event.h
===================================================================
--- src/lib/cligg_event.h 2007-05-14 21:47:41 UTC (rev 49)
+++ src/lib/cligg_event.h 2007-05-15 20:58:37 UTC (rev 50)
@@ -14,7 +14,7 @@
*/
typedef struct cligg_event_data cligg_event_data;
typedef struct cligg_event_function cligg_event_function;
-typedef void* (*cligg_event_cb) (void* data);
+typedef int (*cligg_event_cb) (void* data);
struct cligg_event_data {
char *name; /**< Name */
Modified: src/lib/cligg_hashmap.h
===================================================================
--- src/lib/cligg_hashmap.h 2007-05-14 21:47:41 UTC (rev 49)
+++ src/lib/cligg_hashmap.h 2007-05-15 20:58:37 UTC (rev 50)
@@ -8,18 +8,47 @@
typedef struct cligg_hashmap cligg_hashmap;
typedef struct cligg_hashmap_element cligg_hashmap_element;
+/**
+ * @brief
+ */
struct cligg_hashmap {
cligg_btree *map;
hash_func_cb hash_func;
};
+/**
+ * @brief
+ */
struct cligg_hashmap_element {
unsigned long hash;
void *data;
};
+/**
+ * @brief
+ *
+ * @param free_func_cb
+ * @param hash_func_cb
+ * @param int
+ *
+ * @return
+ */
CLIGG cligg_hashmap *cligg_hashmap_new(free_func_cb, hash_func_cb, int);
+/**
+ * @brief
+ *
+ * @param
+ *
+ * @return
+ */
CLIGG void cligg_hashmap_clear(cligg_hashmap *);
+/**
+ * @brief
+ *
+ * @param
+ *
+ * @return
+ */
CLIGG void cligg_hashmap_del(cligg_hashmap *);
CLIGG int cligg_hashmap_add_element(cligg_hashmap *, void *data);
Modified: src/lib/cligg_list.c
===================================================================
--- src/lib/cligg_list.c 2007-05-14 21:47:41 UTC (rev 49)
+++ src/lib/cligg_list.c 2007-05-15 20:58:37 UTC (rev 50)
@@ -55,6 +55,7 @@
}
free(list->last);
memset(list, 0, sizeof(cligg_list));
+ list->current = NULL;
}
/* delete the list */
@@ -115,10 +116,12 @@
}
new_element->data = data;
new_element->next = NULL;
+ new_element->prev = NULL;
/*append to list*/
if(list->last) {
list->last->next = new_element;
+ new_element->prev = list->last;
}
list->last = new_element;
@@ -145,6 +148,8 @@
return FALSE;
}
new_element->data = data;
+ new_element->next = NULL;
+ new_element->prev = NULL;
/* prepend to list */
new_element->next = list->first;
@@ -164,6 +169,7 @@
CLIGG int cligg_list_list_append(cligg_list *list1, cligg_list *list2)
{
list1->last->next = list2->first;
+ list2->first->prev = list1->last;
list1->last = list2->last;
return TRUE;
}
@@ -171,6 +177,7 @@
/* prepend another list */
CLIGG int cligg_list_list_prepend(cligg_list *list1, cligg_list *list2)
{
+ list1->first->prev = list2->last;
list2->last->next = list1->first;
list1->first = list2->first;
list2->last = list1->first;
@@ -189,12 +196,16 @@
if(list->first == NULL) {
return FALSE;
}
+
+ if(list->current == list->first)
+ list->current = NULL;
old = list->first;
if(list->free_func) {
list->free_func(old->data);
}
list->first = old->next;
+ list->first->prev = NULL;
free(old);
list->size--;
@@ -214,6 +225,9 @@
if(list->last == NULL) {
return FALSE;
}
+
+ if(list->current == list->last)
+ list->current = NULL;
old = list->last;
@@ -269,7 +283,11 @@
i++;
}
+ if(list->current == old)
+ list->current = NULL;
+
previous->next = old->next;
+ previous->next->prev = old->next->prev;
if(list->free_func) {
list->free_func(old->data);
}
@@ -278,6 +296,32 @@
return TRUE;
}
+CLIGG int cligg_list_element_del_current(cligg_list *list)
+{
+ cligg_list_element *tmp;
+
+ if(list->current == NULL)
+ return FALSE;
+
+ if(list->current == list->first)
+ return cligg_list_element_del_first(list);
+ if(list->current == list->last)
+ return cligg_list_element_del_last(list);
+
+ tmp = list->current;
+ list->current->next = list->current->next->next;
+ list->current = list->current->next;
+
+ if(list->free_func)
+ list->free_func(tmp->data);
+
+ tmp->prev->next = tmp->next;
+ tmp->next->prev = tmp->prev;
+
+ free(tmp);
+ return TRUE;
+}
+
/* get list element data*/
CLIGG void* cligg_list_element_get_first(cligg_list *list)
{
@@ -328,17 +372,22 @@
return -1;
}
- if(compare_func(list->last->data, data) == 0)
+ if(compare_func(list->last->data, data) == 0) {
+ list->current = list->last;
return list->size-1;
+ }
tmp = list->first;
while(tmp->next != list->last) {
- if(compare_func(tmp->data, data) == 0)
+ if(compare_func(tmp->data, data) == 0) {
+ list->current = tmp;
return i;
+ }
tmp = tmp->next;
i++;
}
+ list->current = NULL;
return -1;
}
Modified: src/lib/cligg_list.h
===================================================================
--- src/lib/cligg_list.h 2007-05-14 21:47:41 UTC (rev 49)
+++ src/lib/cligg_list.h 2007-05-15 20:58:37 UTC (rev 50)
@@ -36,6 +36,7 @@
struct cligg_list {
cligg_list_element *first; /**< The first element in the list @sa cligg_list_element */
cligg_list_element *last; /**< The last element in the list @sa cligg_list_element */
+ cligg_list_element *current;
free_func_cb free_func; /**< Function pointer to a free function @sa cligg_list_new */
int size; /**< Size of the list */
};
@@ -45,6 +46,7 @@
*/
struct cligg_list_element {
cligg_list_element *next; /**< Pointer to the next element */
+ cligg_list_element *prev;
void *data; /**< Pointer to the data this element holds */
};
@@ -80,6 +82,7 @@
CLIGG int cligg_list_element_del_first(cligg_list *);
CLIGG int cligg_list_element_del_last(cligg_list *);
CLIGG int cligg_list_element_del_index(cligg_list *, int);
+CLIGG int cligg_list_element_del_current(cligg_list *);
/* get list element data*/
CLIGG void* cligg_list_element_get_first(cligg_list *);
Modified: src/lib/cligg_module.c
===================================================================
--- src/lib/cligg_module.c 2007-05-14 21:47:41 UTC (rev 49)
+++ src/lib/cligg_module.c 2007-05-15 20:58:37 UTC (rev 50)
@@ -1,3 +1,30 @@
-#define BLUBB "MAEEH!!!"
+#include <stdlib.h>
+#include <string.h>
+#include <cligg_module.h>
-void blubb(){}
+cligg_module *
+cligg_module_new(char *path)
+{
+ cligg_module *new = (cligg_module *)malloc(sizeof(cligg_module));
+ if(new == NULL)
+ return NULL;
+
+ new->path = (char *)malloc(strlen(path)+1 * sizeof(char));
+ if(new->path == NULL) {
+ free(new);
+ return NULL;
+ }
+
+ new->path = strcpy(new->path, path);
+ new->handle = NULL;
+
+ return new;
+}
+
+void cligg_module_del(void *module)
+{
+ cligg_module *old = (cligg_module *)module;
+
+ free(old->path);
+ free(old);
+}
Modified: src/lib/cligg_module.h
===================================================================
--- src/lib/cligg_module.h 2007-05-14 21:47:41 UTC (rev 49)
+++ src/lib/cligg_module.h 2007-05-15 20:58:37 UTC (rev 50)
@@ -5,7 +5,7 @@
*/
#ifndef CLIGG_MODULE_H
-#define CLIGG_MODULE_C
+#define CLIGG_MODULE_H
/**
* @defgroup load_modules Official loadable modules for cligg
@@ -18,14 +18,24 @@
* @{
*/
+#ifndef CLIGG_MODULE
+# define CLIGG_MODULE
+# define cligg_module_init void __attribute__ ((constructor))
+# define cligg_module_finit void __attribute__ ((destructor))
+#endif
+
+
typedef struct cligg_module cligg_module;
/*this is likely to be changed soon */
struct cligg_module {
- char *name ;
- void *(*module_init)();
+ char *path;
+ void *handle;
};
+cligg_module *cligg_module_new(char *);
+void cligg_module_del(void *);
+
/** @} */
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|