Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * hook.c 00003 * Copyright 2011 John Lindgren 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions, and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions, and the following disclaimer in the documentation 00013 * provided with the distribution. 00014 * 00015 * This software is provided "as is" and without any warranty, express or 00016 * implied. In no event shall the authors be liable for any damages arising from 00017 * the use of this software. 00018 */ 00019 00020 #include <glib.h> 00021 #include <pthread.h> 00022 #include <string.h> 00023 00024 #include "config.h" 00025 #include "core.h" 00026 #include "hook.h" 00027 00028 typedef struct { 00029 HookFunction func; 00030 void * user; 00031 } HookItem; 00032 00033 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 00034 static GHashTable * hooks; 00035 00036 /* str_unref() may be a macro */ 00037 static void str_unref_cb (void * str) 00038 { 00039 str_unref (str); 00040 } 00041 00042 EXPORT void hook_associate (const char * name, HookFunction func, void * user) 00043 { 00044 pthread_mutex_lock (& mutex); 00045 00046 if (! hooks) 00047 hooks = g_hash_table_new_full (g_str_hash, g_str_equal, str_unref_cb, NULL); 00048 00049 HookItem * item = g_slice_new (HookItem); 00050 item->func = func; 00051 item->user = user; 00052 00053 GList * items = g_hash_table_lookup (hooks, name); 00054 items = g_list_prepend (items, item); 00055 g_hash_table_insert (hooks, str_get (name), items); 00056 00057 pthread_mutex_unlock (& mutex); 00058 } 00059 00060 EXPORT void hook_dissociate_full (const char * name, HookFunction func, void * user) 00061 { 00062 pthread_mutex_lock (& mutex); 00063 00064 if (! hooks) 00065 goto DONE; 00066 00067 GList * items = g_hash_table_lookup (hooks, name); 00068 00069 GList * node = items; 00070 while (node) 00071 { 00072 HookItem * item = node->data; 00073 GList * next = node->next; 00074 00075 if (item->func == func && (! user || item->user == user)) 00076 { 00077 items = g_list_delete_link (items, node); 00078 g_slice_free (HookItem, item); 00079 } 00080 00081 node = next; 00082 } 00083 00084 if (items) 00085 g_hash_table_insert (hooks, str_get (name), items); 00086 else 00087 g_hash_table_remove (hooks, name); 00088 00089 DONE: 00090 pthread_mutex_unlock (& mutex); 00091 } 00092 00093 EXPORT void hook_call (const char * name, void * data) 00094 { 00095 pthread_mutex_lock (& mutex); 00096 00097 if (! hooks) 00098 goto DONE; 00099 00100 GList * node = g_hash_table_lookup (hooks, name); 00101 00102 for (; node; node = node->next) 00103 { 00104 HookItem * item = node->data; 00105 item->func (data, item->user); 00106 } 00107 00108 DONE: 00109 pthread_mutex_unlock (& mutex); 00110 }