diff options
author | Tim Janik <timj@gtk.org> | 1998-12-21 21:43:00 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-12-21 21:43:00 +0000 |
commit | 097c9b17985efe03bf7d5a1b073d81f526218c87 (patch) | |
tree | c74e266ccd11d53c49c934a7d7876f27f97dcc2f /ghook.c | |
parent | 85755f7e77f5283cc13d2e8f7d841d2e151bfc33 (diff) |
there was a reference count race for hooks during invocation loops. since
Mon Dec 21 21:48:29 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gmain.c: there was a reference count race for hooks during invocation
loops. since all (known) hook loop implementations, do currently start
out with g_hook_first_valid() and iterate with g_hook_next_valid(),
g_hook_first_valid() will now return a referenced hook, and
g_hook_next_valid() will "eat" that, and eventually transfer it to
the next hook. <sigh> unfortunately this requires g_hook_next_valid()
to take the hook_list as additional argument.
* gmain.c (g_main_iterate): adjusted callers of g_hook_next_valid().
Diffstat (limited to 'ghook.c')
-rw-r--r-- | ghook.c | 30 |
1 files changed, 21 insertions, 9 deletions
@@ -286,7 +286,7 @@ g_hook_list_invoke (GHookList *hook_list, if (!was_in_call) hook->flags &= ~G_HOOK_FLAG_IN_CALL; - tmp = g_hook_next_valid (hook, may_recurse); + tmp = g_hook_next_valid (hook_list, hook, may_recurse); g_hook_unref (hook_list, hook); hook = tmp; @@ -321,7 +321,7 @@ g_hook_list_invoke_check (GHookList *hook_list, if (need_destroy) g_hook_destroy_link (hook_list, hook); - tmp = g_hook_next_valid (hook, may_recurse); + tmp = g_hook_next_valid (hook_list, hook, may_recurse); g_hook_unref (hook_list, hook); hook = tmp; @@ -357,7 +357,7 @@ g_hook_list_marshal_check (GHookList *hook_list, if (need_destroy) g_hook_destroy_link (hook_list, hook); - tmp = g_hook_next_valid (hook, may_recurse); + tmp = g_hook_next_valid (hook_list, hook, may_recurse); g_hook_unref (hook_list, hook); hook = tmp; @@ -390,7 +390,7 @@ g_hook_list_marshal (GHookList *hook_list, if (!was_in_call) hook->flags &= ~G_HOOK_FLAG_IN_CALL; - tmp = g_hook_next_valid (hook, may_recurse); + tmp = g_hook_next_valid (hook_list, hook, may_recurse); g_hook_unref (hook_list, hook); hook = tmp; @@ -408,12 +408,13 @@ g_hook_first_valid (GHookList *hook_list, GHook *hook; hook = hook_list->hooks; + g_hook_ref (hook_list, hook); if (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); } } @@ -421,9 +422,14 @@ g_hook_first_valid (GHookList *hook_list, } 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; @@ -431,10 +437,16 @@ g_hook_next_valid (GHook *hook, 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; } |