there was a reference count race for hooks during invocation loops. since
authorTim Janik <timj@gtk.org>
Mon, 21 Dec 1998 21:43:00 +0000 (21:43 +0000)
committerTim Janik <timj@src.gnome.org>
Mon, 21 Dec 1998 21:43:00 +0000 (21:43 +0000)
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().

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
ghook.c
glib.h
glib/ghook.c
glib/glib.h
glib/gmain.c
gmain.c

index db644f3..07e4961 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index db644f3..07e4961 100644 (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
index db644f3..07e4961 100644 (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
index db644f3..07e4961 100644 (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
index db644f3..07e4961 100644 (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
index db644f3..07e4961 100644 (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
index db644f3..07e4961 100644 (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
index db644f3..07e4961 100644 (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
diff --git a/ghook.c b/ghook.c
index b683b7c..8705e63 100644 (file)
--- a/ghook.c
+++ b/ghook.c
@@ -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;
 }
 
diff --git a/glib.h b/glib.h
index 19c6dd7..fe6688c 100644 (file)
--- a/glib.h
+++ b/glib.h
@@ -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 */
index b683b7c..8705e63 100644 (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,
-                  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;
 }
 
index 19c6dd7..fe6688c 100644 (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 */
index 360821d..2a5e25a 100644 (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;
diff --git a/gmain.c b/gmain.c
index 360821d..2a5e25a 100644 (file)
--- a/gmain.c
+++ b/gmain.c
@@ -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;