00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <glib.h>
00021 #include <pthread.h>
00022 #include <string.h>
00023
00024 #include "core.h"
00025 #include "hook.h"
00026
00027 typedef struct {
00028 HookFunction func;
00029 void * user;
00030 } HookItem;
00031
00032 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
00033 static GHashTable * hooks;
00034
00035
00036 static void str_unref_cb (void * str)
00037 {
00038 str_unref (str);
00039 }
00040
00041 void hook_associate (const char * name, HookFunction func, void * user)
00042 {
00043 pthread_mutex_lock (& mutex);
00044
00045 if (! hooks)
00046 hooks = g_hash_table_new_full (g_str_hash, g_str_equal, str_unref_cb, NULL);
00047
00048 HookItem * item = g_slice_new (HookItem);
00049 item->func = func;
00050 item->user = user;
00051
00052 GList * items = g_hash_table_lookup (hooks, name);
00053 items = g_list_prepend (items, item);
00054 g_hash_table_insert (hooks, str_get (name), items);
00055
00056 pthread_mutex_unlock (& mutex);
00057 }
00058
00059 void hook_dissociate_full (const char * name, HookFunction func, void * user)
00060 {
00061 pthread_mutex_lock (& mutex);
00062
00063 if (! hooks)
00064 goto DONE;
00065
00066 GList * items = g_hash_table_lookup (hooks, name);
00067
00068 GList * node = items;
00069 while (node)
00070 {
00071 HookItem * item = node->data;
00072 GList * next = node->next;
00073
00074 if (item->func == func && (! user || item->user == user))
00075 {
00076 items = g_list_delete_link (items, node);
00077 g_slice_free (HookItem, item);
00078 }
00079
00080 node = next;
00081 }
00082
00083 if (items)
00084 g_hash_table_insert (hooks, str_get (name), items);
00085 else
00086 g_hash_table_remove (hooks, name);
00087
00088 DONE:
00089 pthread_mutex_unlock (& mutex);
00090 }
00091
00092 void hook_call (const char * name, void * data)
00093 {
00094 pthread_mutex_lock (& mutex);
00095
00096 if (! hooks)
00097 goto DONE;
00098
00099 GList * node = g_hash_table_lookup (hooks, name);
00100
00101 for (; node; node = node->next)
00102 {
00103 HookItem * item = node->data;
00104 item->func (data, item->user);
00105 }
00106
00107 DONE:
00108 pthread_mutex_unlock (& mutex);
00109 }