]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
Allow ply-trigger to have multiple pull handlers
authorRay Strode <rstrode@redhat.com>
Thu, 25 Sep 2008 04:00:58 +0000 (00:00 -0400)
committerRay Strode <rstrode@redhat.com>
Mon, 29 Sep 2008 03:40:27 +0000 (23:40 -0400)
This will be useful for hooking into a trigger
at multiple layers in the code.

src/libply/ply-trigger.c
src/libply/ply-trigger.h
src/ply-boot-splash.c

index 83131a0b9e49346d88fa69906dd2ea7647b48cf4..b1952d71cdabb94f1d1c73f620f4a82a870000d2 100644 (file)
 #include <string.h>
 
 #include "ply-logger.h"
+#include "ply-list.h"
 #include "ply-utils.h"
 
-struct _ply_trigger
+typedef struct
 {
   ply_trigger_handler_t  handler;
   void                  *user_data;
-  ply_trigger_t         **free_address;
+} ply_trigger_closure_t;
+
+struct _ply_trigger
+{
+  ply_list_t *closures;
+
+  ply_trigger_t **free_address;
 };
 
 ply_trigger_t *
-ply_trigger_new (ply_trigger_handler_t  handler,
-                 void                 *user_data,
-                 ply_trigger_t       **free_address)
+ply_trigger_new (ply_trigger_t **free_address)
 {
   ply_trigger_t *trigger;
 
   trigger = calloc (1, sizeof (ply_trigger_t));
-  trigger->handler = handler;
-  trigger->user_data = user_data;
   trigger->free_address = free_address;
+  trigger->closures = ply_list_new ();
 
   return trigger;
 }
@@ -54,23 +58,101 @@ ply_trigger_new (ply_trigger_handler_t  handler,
 void
 ply_trigger_free (ply_trigger_t *trigger)
 {
+  ply_list_node_t *node;
+
   if (trigger == NULL)
     return;
 
+  node = ply_list_get_first_node (trigger->closures);
+  while (node != NULL)
+    {
+      ply_list_node_t *next_node;
+      ply_trigger_closure_t *closure;
+
+      closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
+
+      next_node = ply_list_get_next_node (trigger->closures, node);
+
+      free (closure);
+      ply_list_remove_node (trigger->closures, node);
+
+      node = next_node;
+    }
+  ply_list_free (trigger->closures);
+
+  if (trigger->free_address != NULL)
+    *trigger->free_address = NULL;
+
   if (trigger->free_address != NULL)
     *trigger->free_address = NULL;
 
   free (trigger);
 }
 
+void
+ply_trigger_add_handler (ply_trigger_t         *trigger,
+                         ply_trigger_handler_t  handler,
+                         void                  *user_data)
+{
+  ply_trigger_closure_t *closure;
+
+  closure = calloc (1, sizeof (ply_trigger_closure_t));
+  closure->handler = handler;
+  closure->user_data = user_data;
+
+  ply_list_append_data (trigger->closures, closure);
+}
+
+void
+ply_trigger_remove_handler (ply_trigger_t         *trigger,
+                            ply_trigger_handler_t  handler,
+                            void                  *user_data)
+{
+  ply_list_node_t *node;
+
+  node = ply_list_get_first_node (trigger->closures);
+  while (node != NULL)
+    {
+      ply_list_node_t *next_node;
+      ply_trigger_closure_t *closure;
+
+      closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
+
+      next_node = ply_list_get_next_node (trigger->closures, node);
+
+      if (closure->handler == handler && closure->user_data == user_data)
+        {
+          free (closure);
+          ply_list_remove_node (trigger->closures, node);
+          break;
+        }
+
+      node = next_node;
+    }
+}
+
 void
 ply_trigger_pull (ply_trigger_t *trigger,
                   const void    *data)
 {
+  ply_list_node_t *node;
+
   assert (trigger != NULL);
 
-  if (trigger->handler != NULL)
-    trigger->handler (trigger->user_data, data, trigger);
+  node = ply_list_get_first_node (trigger->closures);
+  while (node != NULL)
+    {
+      ply_list_node_t *next_node;
+      ply_trigger_closure_t *closure;
+
+      closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
+
+      next_node = ply_list_get_next_node (trigger->closures, node);
+
+      closure->handler (closure->user_data, data, trigger);
+
+      node = next_node;
+    }
 
   if (trigger->free_address != NULL)
     ply_trigger_free (trigger);
index d7dc936d99e3557a3b466680efd801d83e8b4a35..cf9fbf091de499628d5cb432c55a42d9486efe65 100644 (file)
@@ -34,9 +34,14 @@ typedef void (* ply_trigger_handler_t) (void          *user_data,
                                         const void    *trigger_data,
                                         ply_trigger_t *trigger);
 #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
-ply_trigger_t *ply_trigger_new (ply_trigger_handler_t  handler,
-                                void                 *user_data,
-                                ply_trigger_t       **post_pull_free_address);
+ply_trigger_t *ply_trigger_new (ply_trigger_t **free_address);
+
+void ply_trigger_add_handler (ply_trigger_t          *trigger,
+                              ply_trigger_handler_t   handler,
+                              void                   *user_data);
+void ply_trigger_remove_handler (ply_trigger_t         *trigger,
+                                 ply_trigger_handler_t  handler,
+                                 void                  *user_data);
 void ply_trigger_free (ply_trigger_t *trigger);
 
 void ply_trigger_pull (ply_trigger_t *trigger,
index 844116a0f45e3a6f05ac895441d6141b8b623619..46bd21ab19eee8fb9629e0ccaf5abf96532ca37b 100644 (file)
@@ -308,7 +308,10 @@ ply_boot_splash_become_idle (ply_boot_splash_t                  *splash,
       return;
     }
 
-  splash->idle_trigger = ply_trigger_new ((ply_trigger_handler_t) idle_handler, user_data, &splash->idle_trigger);
+  splash->idle_trigger = ply_trigger_new (&splash->idle_trigger);
+  ply_trigger_add_handler (splash->idle_trigger,
+                           (ply_trigger_handler_t) idle_handler,
+                           user_data);
 
   splash->plugin_interface->become_idle (splash->plugin, splash->idle_trigger);
 }