[PATCH] Make hotplugging non-recursive.

Rob Taylor rob.taylor at codethink.co.uk
Wed Jan 31 08:03:47 PST 2007


Ok to commit?

This adds a notify callback for when hald_runner has finished calling a
callout.
For linux, we install hotplug_event_process_queue as the notify, and
modify hotplug_event_process_queue to iterate the queue. All recrursive
calls to hotplug_event_process_queue are removed. This results in
massive stack and a not inconsiquential heap savings.
---
 hald/hald_runner.c    |   17 ++++++++++++++++-
 hald/hald_runner.h    |    3 +++
 hald/linux/blockdev.c |    2 --
 hald/linux/hotplug.c  |   38 ++++++++++++++++++--------------------
 hald/linux/osspec.c   |    5 ++---
 5 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index 41fa987..95edbec 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -54,6 +54,8 @@ typedef struct {
 #define DBUS_SERVER_ADDRESS "unix:tmpdir=" HALD_SOCKET_DIR

 static DBusConnection *runner_connection = NULL;
+static HaldRunnerRunNotify method_run_notify = NULL;
+static gpointer method_run_notify_userdata = NULL;

 typedef struct
 {
@@ -526,7 +528,9 @@ call_notify(DBusPendingCall *pending, vo
   g_free (hb);

   dbus_pending_call_unref (pending);
-  return;
+
+  goto out;
+
 malformed:
   /* Send a Fail callback on malformed messages */
   HAL_ERROR (("Malformed or unexpected reply message"));
@@ -541,6 +545,10 @@ malformed:
   g_free (hb);

   dbus_pending_call_unref (pending);
+
+out:
+  if (method_run_notify)
+    method_run_notify (method_run_notify_userdata);
 }

 /* Run a helper program using the commandline, with input as infomation on
@@ -661,3 +669,10 @@ hald_runner_kill_all(HalDevice *device)

   dbus_message_unref(msg);
 }
+
+void
+hald_runner_set_method_run_notify (HaldRunnerRunNotify cb, gpointer
user_data)
+{
+  method_run_notify = cb;
+  method_run_notify_userdata = user_data;
+}
diff --git a/hald/hald_runner.h b/hald/hald_runner.h
index 0fc2425..4dc1267 100644
--- a/hald/hald_runner.h
+++ b/hald/hald_runner.h
@@ -83,4 +83,7 @@ void hald_runner_kill_all();
 /* called by the core to tell the runner a device was finalized */
 void runner_device_finalized (HalDevice *device);

+typedef void (*HaldRunnerRunNotify)(gpointer user_data);
+void hald_runner_set_method_run_notify (HaldRunnerRunNotify cb,
gpointer user_data);
+
 #endif
diff --git a/hald/linux/blockdev.c b/hald/linux/blockdev.c
index 52c6071..55f22f1 100644
--- a/hald/linux/blockdev.c
+++ b/hald/linux/blockdev.c
@@ -315,7 +315,6 @@ generate_fakevolume_hotplug_event_add_fo
 	hotplug_event->sysfs.net_ifindex = -1;

 	hotplug_event_enqueue (hotplug_event);
-	hotplug_event_process_queue ();
 }

 static void
@@ -1303,7 +1302,6 @@ block_rescan_storage_done (HalDevice *d,
 			hotplug_event = blockdev_generate_remove_hotplug_event (fakevolume);
 			if (hotplug_event != NULL) {
 				hotplug_event_enqueue (hotplug_event);
-				hotplug_event_process_queue ();
 			}
 		}
 	}
diff --git a/hald/linux/hotplug.c b/hald/linux/hotplug.c
index b5e62bf..986b96c 100644
--- a/hald/linux/hotplug.c
+++ b/hald/linux/hotplug.c
@@ -67,7 +67,6 @@ hotplug_event_end (void *end_token)
 	} else {
 		g_free (hotplug_event);
 	}
-	hotplug_event_process_queue ();
 }

 void
@@ -76,7 +75,6 @@ hotplug_event_reposted (void *end_token)
 	HotplugEvent *hotplug_event = (HotplugEvent *) end_token;

 	hotplug_events_in_progress = g_slist_remove
(hotplug_events_in_progress, hotplug_event);
-	hotplug_event_process_queue ();
 }

 static void
@@ -305,29 +303,29 @@ hotplug_event_process_queue (void)
 {
 	HotplugEvent *hotplug_event;

-	if (hotplug_events_in_progress == NULL &&
-	    (hotplug_event_queue == NULL || g_queue_is_empty
(hotplug_event_queue))) {
-		hotplug_queue_now_empty ();
-		goto out;
-	}
+        while (hotplug_events_in_progress != NULL ||
+		(hotplug_event_queue != NULL &&
+		 !g_queue_is_empty (hotplug_event_queue))) {

-	/* do not process events if some other event is in progress
-	 *
-	 * TODO: optimize so we can do add events in parallel by inspecting the
-	 *       wait_for_sysfs_path parameter and hotplug_events_in_progress list
-	 */
-	if (hotplug_events_in_progress != NULL && g_slist_length
(hotplug_events_in_progress) > 0)
-		goto out;
+		/* do not process events if some other event is in progress
+		 *
+		 * TODO: optimize so we can do add events in parallel by inspecting the
+		 *       wait_for_sysfs_path parameter and hotplug_events_in_progress
list
+		 */
+		if (hotplug_events_in_progress != NULL && g_slist_length
(hotplug_events_in_progress) > 0)
+			goto out;

-	hotplug_event = g_queue_pop_head (hotplug_event_queue);
-	if (hotplug_event == NULL)
-		goto out;
+		hotplug_event = g_queue_pop_head (hotplug_event_queue);
+		if (hotplug_event == NULL)
+			goto out;

-	hotplug_events_in_progress = g_slist_append
(hotplug_events_in_progress, hotplug_event);
-	hotplug_event_begin (hotplug_event);
+		hotplug_events_in_progress = g_slist_append
(hotplug_events_in_progress, hotplug_event);
+		hotplug_event_begin (hotplug_event);
+	}

+	hotplug_queue_now_empty ();
 out:
-	;	
+        ;
 }

 gboolean
diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c
index 12047e0..1fdf90a 100644
--- a/hald/linux/osspec.c
+++ b/hald/linux/osspec.c
@@ -335,9 +335,6 @@ computer_callouts_add_done (HalDevice *d
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
 	hal_device_store_add (hald_get_gdl (), d);
-
-	/* start processing events */
-	hotplug_event_process_queue ();
 }

 void
@@ -579,6 +576,8 @@ osspec_probe (void)

 	should_decode_dmi = FALSE;

+	hald_runner_set_method_run_notify (hotplug_event_process_queue,
+					   NULL);
 	root = hal_device_new ();
 	hal_device_property_set_string (root, "info.bus", "unknown");
 	hal_device_property_set_string (root, "info.product", "Computer");


More information about the hal mailing list