hal/hald/linux osspec.c,1.38,1.39

David Zeuthen david at freedesktop.org
Tue Aug 31 15:55:46 PDT 2004


Update of /cvs/hal/hal/hald/linux
In directory gabe:/tmp/cvs-serv5912/hald/linux

Modified Files:
	osspec.c 
Log Message:
2004-09-01  David Zeuthen  <david at fubar.dk>

	This was a fun debugging session that led to this fix :-)
	Basically when building optimized binaries (like for the Fedora
	RPMS) an interesting sideeffect showed up: gobject signal handlers
	are run in arbritrary order. This means that we were processing
	hotplug events for sda%d before sda was added; which resulted in
	the unavailability of the kids because they couldn't find their
	parent.  Now we look at the device store to infer when to process
	the next event. Which is more correct and actually makes hal
	work. This *never* once showed up when not building without
	--build=i686-redhat-linux-gnu --host=i686-redhat-linux-gnu
	--target=i386-redhat-linux-gnu. Oh well.

	* hald/linux/osspec.c (process_coldplug_list_on_gdl_store_add): 
	Renamed from _callouts_done_for_device
	(process_coldplug_list): Wait for device to be added to GDL instead
	of relying on callouts to complete (device obj may not have been added
	to GDL just because the callouts complete)
	(reenable_hotplug_on_gdl_store_add): Renamed from reeanble_hotplug_proc
	(reenable_hotplug_on_gdl_store_remove): New function
	(hald_helper_hotplug): Rather look at the GDL for additions and
	removals than looking at whether callouts complete



Index: osspec.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/osspec.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- osspec.c	28 Aug 2004 13:35:47 -0000	1.38
+++ osspec.c	31 Aug 2004 22:55:44 -0000	1.39
@@ -703,34 +703,37 @@
 	return;
 }
 
-static void process_coldplug_list (GSList *coldplug_list);
+/* global list of devices to be coldplugged */
+static GSList *coldplug_list;
+
+static void process_coldplug_list ();
 
 static void process_coldplug_list_device_cancelled (HalDevice *device, gpointer user_data);
 
 static void
-process_coldplug_list_callouts_done_for_device (HalDevice *device, gpointer user_data)
+process_coldplug_list_on_gdl_store_add (HalDeviceStore *store, HalDevice *device, gboolean is_added, gpointer user_data)
 {
-	GSList *coldplug_list = user_data;
+	HalDevice *waiting_device = (HalDevice *) user_data;
 
-	g_signal_handlers_disconnect_by_func (device, process_coldplug_list_callouts_done_for_device, user_data);
-	g_signal_handlers_disconnect_by_func (device, process_coldplug_list_device_cancelled, user_data);
+	if (waiting_device == device && is_added) {
+		g_signal_handlers_disconnect_by_func (store, process_coldplug_list_on_gdl_store_add, user_data);
+		g_signal_handlers_disconnect_by_func (device, process_coldplug_list_device_cancelled, user_data);
 
-	process_coldplug_list (coldplug_list);
+		process_coldplug_list ();
+	}
 }
 
 static void
 process_coldplug_list_device_cancelled (HalDevice *device, gpointer user_data)
 {
-	GSList *coldplug_list = user_data;
-
-	g_signal_handlers_disconnect_by_func (device, process_coldplug_list_callouts_done_for_device, user_data);
+	g_signal_handlers_disconnect_by_func (hald_get_gdl (), process_coldplug_list_on_gdl_store_add, user_data);
 	g_signal_handlers_disconnect_by_func (device, process_coldplug_list_device_cancelled, user_data);
 
-	process_coldplug_list (coldplug_list);
+	process_coldplug_list ();
 }
 
 static void
-process_coldplug_list (GSList *coldplug_list)
+process_coldplug_list ()
 {
 	gchar *path;
 	gchar *subsystem;
@@ -751,12 +754,16 @@
 		g_free (pair);
 
 		if (device != NULL && hal_device_store_find(hald_get_gdl (), device->udi) == NULL) {
-			g_signal_connect (device, "callouts_finished",
-					  G_CALLBACK (process_coldplug_list_callouts_done_for_device), coldplug_list);
+
+			/* wait until we are in GDL */
+			g_signal_connect (hald_get_gdl (), "store_changed", 
+					  G_CALLBACK (process_coldplug_list_on_gdl_store_add), device);
+
+			/* or until we are cancelled */
 			g_signal_connect (device, "cancelled",
-					  G_CALLBACK (process_coldplug_list_device_cancelled), coldplug_list);
+					  G_CALLBACK (process_coldplug_list_device_cancelled), device);
 		} else {
-			process_coldplug_list (coldplug_list);
+			process_coldplug_list ();
 		}
 
 
@@ -773,8 +780,6 @@
 static void
 add_computer_callouts_done (HalDevice *device, gpointer user_data)
 {
-	GSList *coldplug_list = user_data;
-
 	g_object_ref (device);
 	hal_device_store_remove (hald_get_tdl (), device);
 	hal_device_store_add (hald_get_gdl (), device);
@@ -783,7 +788,7 @@
 					      user_data);
 	g_object_unref (device);
 
-	process_coldplug_list (coldplug_list);
+	process_coldplug_list ();
 }
 
 
@@ -791,7 +796,6 @@
 void
 osspec_probe (void)
 {
-	GSList *coldplug_list;
 	HalDevice *root;
 	struct utsname un;
 	
@@ -1095,24 +1099,49 @@
 	process_shutdown_list (shutdown_list);
 }
 
-static void reenable_hotplug_proc (HalDevice *d, gpointer user_data);
+static void reenable_hotplug_proc_on_device_cancel (HalDevice *d, gpointer user_data);
+
+static void
+reenable_hotplug_on_gdl_store_add (HalDeviceStore *store, HalDevice *device, gboolean is_added, gpointer user_data)
+{
+	HalDevice *waiting_device = (HalDevice *) user_data;
+
+	if (waiting_device == device && is_added) {
+		/* unregister signal handlers */
+		g_signal_handlers_disconnect_by_func (store, reenable_hotplug_on_gdl_store_add, user_data);
+		g_signal_handlers_disconnect_by_func (device, reenable_hotplug_proc_on_device_cancel, user_data);
+
+		/* continue processing */
+		hotplug_sem_down ();
+	}
+}
 
 static void
 reenable_hotplug_proc_on_device_cancel (HalDevice *d, gpointer user_data)
 {
-	g_signal_handlers_disconnect_by_func (d, reenable_hotplug_proc_on_device_cancel, user_data);
-	g_signal_handlers_disconnect_by_func (d, reenable_hotplug_proc, user_data);
-	hotplug_sem_down ();
+	/* unregister signal handlers */
+	g_signal_handlers_disconnect_by_func (hald_get_gdl (), reenable_hotplug_on_gdl_store_add, user_data);
+        g_signal_handlers_disconnect_by_func (d, reenable_hotplug_proc_on_device_cancel, user_data);
+
+	/* continue processing */
+        hotplug_sem_down ();
 }
 
 static void
-reenable_hotplug_proc (HalDevice *d, gpointer user_data)
+reenable_hotplug_on_gdl_store_remove (HalDeviceStore *store, HalDevice *device, gboolean is_added, gpointer user_data)
 {
-	g_signal_handlers_disconnect_by_func (d, reenable_hotplug_proc_on_device_cancel, user_data);
-	g_signal_handlers_disconnect_by_func (d, reenable_hotplug_proc, user_data);
-	hotplug_sem_down ();
+	HalDevice *waiting_device = (HalDevice *) user_data;
+
+	if (waiting_device == device && !is_added) {
+		/* unregister signal handlers */
+		g_signal_handlers_disconnect_by_func (store, reenable_hotplug_on_gdl_store_remove, user_data);
+
+		/* continue processing */
+		hotplug_sem_down ();
+	}
 }
 
+
 static void
 hald_helper_hotplug (gboolean is_add, int seqnum, gchar *subsystem, gchar *sysfs_path)
 {
@@ -1135,11 +1164,20 @@
 			
 			/* Disable hotplug processing for now */
 			hotplug_sem_up ();
-			g_signal_connect (d, "callouts_finished",
-					  G_CALLBACK (reenable_hotplug_proc), NULL);
-			/* device may also be cancelled if e.g. no device file is found */
-			g_signal_connect (d, "cancelled",
-					  G_CALLBACK (reenable_hotplug_proc_on_device_cancel), NULL);
+
+			/* wait until we are in GDL */
+			g_signal_connect (hald_get_gdl (), "store_changed", 
+					  G_CALLBACK (reenable_hotplug_on_gdl_store_add), d);
+
+			/* or until we are cancelled */
+			g_signal_connect (d, "cancelled", G_CALLBACK (reenable_hotplug_proc_on_device_cancel), d);
+
+		} else {
+			if (d != NULL) {
+				HAL_ERROR (("d = 0x%08x", d->udi));
+			} else {
+				HAL_ERROR (("d is NULL!"));
+			}
 		}
 	} else {
 		d = rem_device (sysfs_path_full, subsystem);
@@ -1151,8 +1189,10 @@
 			
 			/* Disable hotplug processing for now */
 			hotplug_sem_up ();
-			g_signal_connect (d, "callouts_finished",
-					  G_CALLBACK (reenable_hotplug_proc), NULL);
+
+			/* wait until we are out of the GDL */
+			g_signal_connect (hald_get_gdl (), "store_changed", 
+					  G_CALLBACK (reenable_hotplug_on_gdl_store_remove), d);
 		}
 	}
 




More information about the hal-commit mailing list