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().
This commit is contained in:
Tim Janik 1998-12-21 21:43:00 +00:00 committed by Tim Janik
parent 85755f7e77
commit 097c9b1798
14 changed files with 166 additions and 28 deletions

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

View File

@ -1,3 +1,16 @@
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().
Mon Dec 21 03:48:04 1998 Tim Janik <timj@gtk.org>
* gmain.c (g_main_iterate): default initialize source_timeout with -1

24
ghook.c
View File

@ -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,
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,9 +437,15 @@ g_hook_next_valid (GHook *hook,
while (hook)
{
if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (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;
}

7
glib.h
View File

@ -1183,9 +1183,14 @@ GHook* g_hook_find_func_data (GHookList *hook_list,
gboolean need_valids,
gpointer func,
gpointer data);
/* return the first valid hook, and increment its reference count */
GHook* g_hook_first_valid (GHookList *hook_list,
gboolean may_be_in_call);
GHook* g_hook_next_valid (GHook *hook,
/* return the next valid hook with incremented reference count, and
* decrement the reference count of the original hook
*/
GHook* g_hook_next_valid (GHookList *hook_list,
GHook *hook,
gboolean may_be_in_call);
/* GHookCompareFunc implementation to insert hooks sorted by their id */

View File

@ -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,
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,9 +437,15 @@ g_hook_next_valid (GHook *hook,
while (hook)
{
if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (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;
}

View File

@ -1183,9 +1183,14 @@ GHook* g_hook_find_func_data (GHookList *hook_list,
gboolean need_valids,
gpointer func,
gpointer data);
/* return the first valid hook, and increment its reference count */
GHook* g_hook_first_valid (GHookList *hook_list,
gboolean may_be_in_call);
GHook* g_hook_next_valid (GHook *hook,
/* return the next valid hook with incremented reference count, and
* decrement the reference count of the original hook
*/
GHook* g_hook_next_valid (GHookList *hook_list,
GHook *hook,
gboolean may_be_in_call);
/* GHookCompareFunc implementation to insert hooks sorted by their id */

View File

@ -474,7 +474,7 @@ g_main_iterate (gboolean block,
break;
if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
{
hook = g_hook_next_valid (hook, TRUE);
hook = g_hook_next_valid (&source_list, hook, TRUE);
continue;
}
@ -510,7 +510,7 @@ g_main_iterate (gboolean block,
timeout = MIN (timeout, source_timeout);
}
tmp = g_hook_next_valid (hook, TRUE);
tmp = g_hook_next_valid (&source_list, hook, TRUE);
g_hook_unref (&source_list, hook);
hook = tmp;
@ -534,7 +534,7 @@ g_main_iterate (gboolean block,
break;
if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
{
hook = g_hook_next_valid (hook, TRUE);
hook = g_hook_next_valid (&source_list, hook, TRUE);
continue;
}
@ -561,7 +561,7 @@ g_main_iterate (gboolean block,
}
}
tmp = g_hook_next_valid (hook, TRUE);
tmp = g_hook_next_valid (&source_list, hook, TRUE);
g_hook_unref (&source_list, hook);
hook = tmp;

View File

@ -474,7 +474,7 @@ g_main_iterate (gboolean block,
break;
if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
{
hook = g_hook_next_valid (hook, TRUE);
hook = g_hook_next_valid (&source_list, hook, TRUE);
continue;
}
@ -510,7 +510,7 @@ g_main_iterate (gboolean block,
timeout = MIN (timeout, source_timeout);
}
tmp = g_hook_next_valid (hook, TRUE);
tmp = g_hook_next_valid (&source_list, hook, TRUE);
g_hook_unref (&source_list, hook);
hook = tmp;
@ -534,7 +534,7 @@ g_main_iterate (gboolean block,
break;
if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
{
hook = g_hook_next_valid (hook, TRUE);
hook = g_hook_next_valid (&source_list, hook, TRUE);
continue;
}
@ -561,7 +561,7 @@ g_main_iterate (gboolean block,
}
}
tmp = g_hook_next_valid (hook, TRUE);
tmp = g_hook_next_valid (&source_list, hook, TRUE);
g_hook_unref (&source_list, hook);
hook = tmp;