incremented version number to 1.1.13, bin age 0, interface age 0.
[platform/upstream/glib.git] / glib / ghook.c
index 91ab097..89c7cfb 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+/* 
+ * MT safe
+ */
+
 #include       "glib.h"
 
 
@@ -43,6 +48,7 @@ g_hook_list_init (GHookList *hook_list,
                                              hook_size * G_HOOKS_PREALLOC,
                                              G_ALLOC_AND_FREE);
   hook_list->hook_free = NULL;
+  hook_list->hook_destroy = NULL;
 }
 
 void
@@ -124,7 +130,12 @@ g_hook_destroy_link (GHookList *hook_list,
     {
       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;
          
@@ -268,12 +279,10 @@ g_hook_list_invoke (GHookList *hook_list,
   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;
@@ -281,10 +290,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);
-      
-      g_hook_unref (hook_list, hook);
-      hook = tmp;
+      hook = g_hook_next_valid (hook_list, hook, may_recurse);
     }
 }
 
@@ -300,13 +306,11 @@ g_hook_list_invoke_check (GHookList *hook_list,
   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;
@@ -316,10 +320,37 @@ 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);
+      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);
     }
 }
 
@@ -338,21 +369,15 @@ g_hook_list_marshal (GHookList                 *hook_list,
   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);
     }
 }
 
@@ -369,10 +394,11 @@ g_hook_first_valid (GHookList *hook_list,
       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);
        }
     }
   
@@ -380,9 +406,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;
   
@@ -390,10 +421,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;
 }