Reduces stack consumption by removing major recusrion paths. diff --git a/hald/linux/blockdev.c b/hald/linux/blockdev.c index b7b2b86..7517d03 100644 --- a/hald/linux/blockdev.c +++ b/hald/linux/blockdev.c @@ -129,6 +130,7 @@ blockdev_callouts_add_done (HalDevice *d hal_device_store_add (hald_get_gdl (), d); hotplug_event_end (end_token); + hotplug_event_process_queue (); } static void @@ -144,6 +146,7 @@ blockdev_callouts_remove_done (HalDevice g_object_unref (d); hotplug_event_end (end_token); + hotplug_event_process_queue (); } static void @@ -345,14 +348,14 @@ add_blockdev_probing_helper_done (HalDev hal_device_store_remove (hald_get_tdl (), d); g_object_unref (d); hotplug_event_end (end_token); - goto out; + goto out2; } if (!blockdev_compute_udi (d)) { hal_device_store_remove (hald_get_tdl (), d); g_object_unref (d); hotplug_event_end (end_token); - goto out; + goto out2; } /* set block.storage_device for storage devices since only now we know the UDI */ @@ -383,6 +386,8 @@ add_blockdev_probing_helper_done (HalDev out: return; +out2: + ; } static void @@ -406,6 +411,7 @@ blockdev_callouts_preprobing_storage_don hal_device_store_add (hald_get_gdl (), d); hotplug_event_end (end_token); + hotplug_event_process_queue (); goto out; } @@ -475,6 +481,7 @@ blockdev_callouts_preprobing_volume_done hal_device_store_add (hald_get_gdl (), d); hotplug_event_end (end_token); + hotplug_event_process_queue (); goto out; } diff --git a/hald/linux/device.c b/hald/linux/device.c index 97c6b62..68e393c 100644 --- a/hald/linux/device.c +++ b/hald/linux/device.c @@ -2729,6 +2729,7 @@ dev_callouts_remove_done (HalDevice *d, g_object_unref (d); hotplug_event_end (end_token); + hotplug_event_process_queue (); } static void @@ -2752,7 +2753,7 @@ add_dev_after_probing (HalDevice *d, Dev hal_util_callout_device_add (d, dev_callouts_add_done, end_token, NULL); out: - ; + ; } static void @@ -2790,6 +2791,7 @@ add_dev_probing_helper_done (HalDevice * add_dev_after_probing (d, handler, end_token); out: + hotplug_event_process_queue (); ; } @@ -2846,17 +2848,16 @@ hotplug_event_begin_add_dev (const gchar HAL_INFO (("add_dev: subsys=%s sysfs_path=%s dev=%s parent_dev=0x%08x", subsystem, sysfs_path, device_file, parent_dev)); - /* update driver property of the parent device, cause manual driver bind/unbind - * may change change this without sending events for the bus device - */ if (parent_dev != NULL) hal_util_set_driver (parent_dev, "info.linux.driver", parent_path); if (parent_dev != NULL && hal_device_property_get_bool (parent_dev, "info.ignore")) { HAL_INFO (("Ignoring add_dev since parent_dev has info.ignore==TRUE")); - hotplug_event_end (end_token); - goto out; + goto out1; } + /* update driver property of the parent device, cause manual driver bind/unbind + * may change change this without sending events for the bus device + */ for (i = 0; dev_handlers [i] != NULL; i++) { DevHandler *handler; @@ -2869,8 +2870,7 @@ hotplug_event_begin_add_dev (const gchar d = handler->add (sysfs_path, device_file, parent_dev, parent_path); if (d == NULL) { /* didn't find anything - thus, ignore this hotplug event */ - hotplug_event_end (end_token); - goto out; + goto out1; } hal_device_property_set_int (d, "linux.hotplug_type", HOTPLUG_EVENT_SYSFS_DEVICE); @@ -2891,6 +2891,7 @@ hotplug_event_begin_add_dev (const gchar } } +out1: /* didn't find anything - thus, ignore this hotplug event */ hotplug_event_end (end_token); out: diff --git a/hald/linux/hotplug.c b/hald/linux/hotplug.c index 1b9282a..aaa5597 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,10 +75,9 @@ 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 +static int hotplug_event_begin_sysfs (HotplugEvent *hotplug_event) { HalDevice *d; @@ -93,8 +91,7 @@ hotplug_event_begin_sysfs (HotplugEvent /* FIXME: we should reprobe the device instead of skipping the event */ if (d != NULL && hotplug_event->action == HOTPLUG_ACTION_ADD) { HAL_ERROR (("devpath %s already present in the store, ignore event", hotplug_event->sysfs.sysfs_path)); - hotplug_event_end ((void *) hotplug_event); - return; + return -1; } /* subsystem "block" are all block devices */ @@ -163,6 +163,8 @@ hotplug_event_begin_sysfs (HotplugEvent parent_path, (void *) hotplug_event); g_free (parent_path); + if(!g_slist_find (hotplug_events_in_progress, hotplug_event)) + return -1; } else if (hotplug_event->action == HOTPLUG_ACTION_REMOVE) { hotplug_event_begin_remove_dev (hotplug_event->sysfs.subsystem, hotplug_event->sysfs.sysfs_path, @@ -200,8 +202,9 @@ hotplug_event_begin_sysfs (HotplugEvent } } else { /* just ignore this hotplug event */ - hotplug_event_end ((void *) hotplug_event); + return -1; } + return 0; } static void @@ -249,7 +252,7 @@ hotplug_event_begin_pmu (HotplugEvent *h } } -static void +static int hotplug_event_begin (HotplugEvent *hotplug_event) { switch (hotplug_event->type) { @@ -258,7 +261,8 @@ hotplug_event_begin (HotplugEvent *hotpl case HOTPLUG_EVENT_SYSFS: case HOTPLUG_EVENT_SYSFS_DEVICE: case HOTPLUG_EVENT_SYSFS_BLOCK: - hotplug_event_begin_sysfs (hotplug_event); + if(hotplug_event_begin_sysfs (hotplug_event)); + return -1; break; case HOTPLUG_EVENT_ACPI: @@ -276,8 +280,10 @@ hotplug_event_begin (HotplugEvent *hotpl default: HAL_ERROR (("Unknown hotplug event type %d", hotplug_event->type)); hotplug_event_end ((void *) hotplug_event); - break; + return -1; } + + return 0; } void @@ -303,26 +309,26 @@ 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); + if(!hotplug_event_begin (hotplug_event)) + goto out; + } + hotplug_queue_now_empty (); out: ; @@ -468,6 +474,5 @@ hotplug_reprobe_tree (HalDevice *d) { hotplug_reprobe_generate_remove_events (d); hotplug_reprobe_generate_add_events (d); - hotplug_event_process_queue (); return FALSE; } diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c index 991dadf..ed76509 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 @@ -624,10 +621,15 @@ osspec_probe (void) if (should_decode_dmi) { hald_runner_run (root, "hald-probe-smbios", NULL, HAL_HELPER_TIMEOUT, computer_probing_pcbios_helper_done, NULL, NULL); + /* start processing events */ + hotplug_event_process_queue (); } else { /* no probing */ probe_openfirmware(root); computer_probing_helper_done (root); + /* start processing events */ + /* don't touch this on removal - it is necessary! */ + hotplug_event_process_queue (); /* eats much of heap (~130K) */ } }