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