[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