From dc602866312bff134f4d827190f5c24934970e19 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Thu, 7 Jan 1999 20:12:19 +0000 Subject: Call the source-specific free function when the hook is freed not when it Thu Jan 7 15:14:08 1999 Owen Taylor * gmain.c (g_source_free_func): Call the source-specific free function when the hook is freed not when it is destroyed; this fixes a bug where a timeout destroyed from itself would access already freed data. --- glib/gmain.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'glib') diff --git a/glib/gmain.c b/glib/gmain.c index eecd18382..ff4c20513 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -82,6 +82,10 @@ struct _GPollRec /* Forward declarations */ +static gint g_source_compare (GHook *a, + GHook *b); +static void g_source_free_func (GHookList *hook_list, + GHook *hook); static void g_main_poll (gint timeout, gboolean use_priority, gint priority); @@ -233,6 +237,15 @@ g_source_compare (GHook *a, return (source_a->priority < source_b->priority) ? -1 : 1; } +static void +g_source_free_func (GHookList *hook_list, + GHook *hook) +{ + GSource *source = (GSource *)hook; + + ((GSourceFuncs *) hook->func)->destroy (source->source_data); +} + guint g_source_add (gint priority, gboolean can_recurse, @@ -249,6 +262,8 @@ g_source_add (gint priority, if (!source_list.is_setup) g_hook_list_init (&source_list, sizeof(GSource)); + source_list.hook_free = g_source_free_func; + source = (GSource *)g_hook_alloc (&source_list); source->priority = priority; source->source_data = source_data; @@ -287,12 +302,7 @@ g_source_remove (guint tag) hook = g_hook_get (&source_list, tag); if (hook) - { - GSource *source = (GSource *)hook; - - ((GSourceFuncs *) source->hook.func)->destroy (source->source_data); - g_hook_destroy_link (&source_list, hook); - } + g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); } @@ -306,12 +316,7 @@ g_source_remove_by_user_data (gpointer user_data) hook = g_hook_find_data (&source_list, TRUE, user_data); if (hook) - { - GSource *source = (GSource *)hook; - - ((GSourceFuncs *) source->hook.func)->destroy (source->source_data); - g_hook_destroy_link (&source_list, hook); - } + g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); } @@ -335,12 +340,7 @@ g_source_remove_by_source_data (gpointer source_data) hook = g_hook_find (&source_list, TRUE, g_source_find_source_data, source_data); if (hook) - { - GSource *source = (GSource *)hook; - - ((GSourceFuncs *) source->hook.func)->destroy (source->source_data); - g_hook_destroy_link (&source_list, hook); - } + g_hook_destroy_link (&source_list, hook); G_UNLOCK (main_loop); } @@ -398,10 +398,7 @@ g_main_dispatch (GTimeVal *current_time) source->hook.flags &= ~G_HOOK_FLAG_IN_CALL; if (need_destroy && G_HOOK_IS_VALID (source)) - { - ((GSourceFuncs *) source->hook.func)->destroy (source->source_data); - g_hook_destroy_link (&source_list, (GHook *) source); - } + g_hook_destroy_link (&source_list, (GHook *) source); } g_hook_unref (&source_list, (GHook*) source); -- cgit v1.2.3