* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+
+/*
+ * MT safe
+ */
+
#include "glib.h"
hook_size * G_HOOKS_PREALLOC,
G_ALLOC_AND_FREE);
hook_list->hook_free = NULL;
+ hook_list->hook_destroy = NULL;
}
void
{
hook->hook_id = 0;
hook->flags &= ~G_HOOK_FLAG_ACTIVE;
- if (hook->destroy)
+ if (hook_list->hook_destroy)
+ {
+ hook_list->hook_destroy (hook_list, hook);
+ hook->destroy = NULL;
+ }
+ else if (hook->destroy)
{
GDestroyNotify destroy;
hook = g_hook_first_valid (hook_list, may_recurse);
while (hook)
{
- GHook *tmp;
GHookFunc func;
gboolean was_in_call;
- g_hook_ref (hook_list, hook);
- func = hook->func;
+ func = (GHookFunc) hook->func;
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
if (!was_in_call)
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
- tmp = g_hook_next_valid (hook, may_recurse);
-
- g_hook_unref (hook_list, hook);
- hook = tmp;
+ hook = g_hook_next_valid (hook_list, hook, may_recurse);
}
}
hook = g_hook_first_valid (hook_list, may_recurse);
while (hook)
{
- GHook *tmp;
GHookCheckFunc func;
gboolean was_in_call;
gboolean need_destroy;
- g_hook_ref (hook_list, hook);
- func = hook->func;
+ func = (GHookCheckFunc) hook->func;
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
if (need_destroy)
g_hook_destroy_link (hook_list, hook);
- tmp = g_hook_next_valid (hook, may_recurse);
+ hook = g_hook_next_valid (hook_list, hook, may_recurse);
+ }
+}
+
+void
+g_hook_list_marshal_check (GHookList *hook_list,
+ gboolean may_recurse,
+ GHookCheckMarshaller marshaller,
+ gpointer data)
+{
+ GHook *hook;
+
+ g_return_if_fail (hook_list != NULL);
+ g_return_if_fail (hook_list->is_setup);
+ g_return_if_fail (marshaller != NULL);
+
+ hook = g_hook_first_valid (hook_list, may_recurse);
+ while (hook)
+ {
+ gboolean was_in_call;
+ gboolean need_destroy;
+
+ was_in_call = G_HOOK_IN_CALL (hook);
+ hook->flags |= G_HOOK_FLAG_IN_CALL;
+ need_destroy = !marshaller (hook, data);
+ if (!was_in_call)
+ hook->flags &= ~G_HOOK_FLAG_IN_CALL;
+ if (need_destroy)
+ g_hook_destroy_link (hook_list, hook);
- g_hook_unref (hook_list, hook);
- hook = tmp;
+ hook = g_hook_next_valid (hook_list, hook, may_recurse);
}
}
hook = g_hook_first_valid (hook_list, may_recurse);
while (hook)
{
- GHook *tmp;
gboolean was_in_call;
- g_hook_ref (hook_list, hook);
-
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
marshaller (hook, data);
if (!was_in_call)
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
- tmp = g_hook_next_valid (hook, may_recurse);
-
- g_hook_unref (hook_list, hook);
- hook = tmp;
+ hook = g_hook_next_valid (hook_list, hook, may_recurse);
}
}
hook = hook_list->hooks;
if (hook)
{
+ g_hook_ref (hook_list, hook);
if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook)))
return hook;
else
- return g_hook_next_valid (hook, may_be_in_call);
+ return g_hook_next_valid (hook_list, hook, may_be_in_call);
}
}
}
GHook*
-g_hook_next_valid (GHook *hook,
- gboolean may_be_in_call)
+g_hook_next_valid (GHookList *hook_list,
+ GHook *hook,
+ gboolean may_be_in_call)
{
+ GHook *ohook = hook;
+
+ g_return_val_if_fail (hook_list != NULL, NULL);
+
if (!hook)
return NULL;
while (hook)
{
if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook)))
- return hook;
+ {
+ g_hook_ref (hook_list, hook);
+ g_hook_unref (hook_list, ohook);
+
+ return hook;
+ }
hook = hook->next;
}
-
+ g_hook_unref (hook_list, ohook);
+
return NULL;
}