hal/hald/linux osspec.c,1.45,1.46

David Zeuthen david at freedesktop.org
Thu Oct 7 07:53:10 PDT 2004


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

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

	* hald/linux/osspec.c (hald_helper_hotplug_process_queue): Have a
	list of hotplug events received during the sleep of the first hotplug
	event and process that in order
	(hotplug_sem_down): Typo in debug output
	(hald_helper_first_hotplug_event): Determine last_hotplug_seqnum by
	looking at list of hotplug events received during the sleep of the
	first hotplug event
	(hald_helper_msg_compare): New function
	(hald_helper_data): Insert, into a sorted list, hotplug events received 
	when sleeping on the first hotplug event
	(FIRST_HOTPLUG_SLEEP): New constant instead of hardcoding 2500 ms



Index: osspec.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/osspec.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- osspec.c	6 Oct 2004 20:23:44 -0000	1.45
+++ osspec.c	7 Oct 2004 14:53:08 -0000	1.46
@@ -58,6 +58,8 @@
 
 #include "libsysfs/libsysfs.h"
 
+#define FIRST_HOTPLUG_SLEEP 3500
+
 extern ClassDeviceHandler input_class_handler;
 extern ClassDeviceHandler net_class_handler;
 extern ClassDeviceHandler printer_class_handler;
@@ -1316,6 +1318,9 @@
 /** queue of hotplug events (struct hald_helper_msg pointers) */
 static GList *hotplug_queue = NULL;
 
+/** queue of hotplug events received when sleeping on the first hotplug event (struct hald_helper_msg pointers) */
+static GList *hotplug_queue_first = NULL;
+
 /** Last hotplug sequence number */
 static guint64 last_hotplug_seqnum = 0;
 
@@ -1332,6 +1337,17 @@
 	if (hotplug_counter > 0)
 		return;
 
+	/* Empty the list of events received while sleeping on the first hotplug event (this list is sorted) */
+	if (hotplug_queue_first != NULL) {
+		msg = (struct hald_helper_msg *) hotplug_queue_first->data;
+		HAL_INFO (("Processing event around first hotplug with SEQNUM=%llu", msg->seqnum));
+		hald_helper_hotplug (msg->action, msg->seqnum, g_strdup (msg->subsystem), 
+				     g_strdup (msg->sysfs_path), msg);
+		g_free (msg);
+		hotplug_queue_first = g_list_delete_link (hotplug_queue_first, hotplug_queue_first);
+		goto trynext;
+	}
+
 	for (i = hotplug_queue; i != NULL; i = g_list_next (i)) {
 		msg = (struct hald_helper_msg *) i->data;
 
@@ -1388,7 +1404,7 @@
 	if (hotplug_counter < 0) {
 		HAL_ERROR (("****************************************"));
 		HAL_ERROR (("****************************************"));
-		HAL_ERROR (("DANGER WILL ROBISON! hotplug semaphore<0!"));
+		HAL_ERROR (("DANGER WILL ROBINSON! hotplug semaphore<0!"));
 		HAL_ERROR (("****************************************"));
 		HAL_ERROR (("****************************************"));
 		hotplug_counter = 0;
@@ -1399,21 +1415,32 @@
 		hald_helper_hotplug_process_queue ();
 }
 
+/** This variable is TRUE exactly when we are sleeping on the first hotplug event */
+static gboolean hotplug_sleep_first_event = FALSE;
+
 static gboolean
 hald_helper_first_hotplug_event (gpointer data)
 {
 	GList *i;
 	struct hald_helper_msg *msg;
 
-	/* find the lowest seqnum we should start with */
-	for (i = hotplug_queue; i != NULL; i = g_list_next (i)) {
+	HAL_INFO (("Slept %dms, now processing events", FIRST_HOTPLUG_SLEEP));
+
+	/* First process the queue of events receieved while sleeping on the first hotplug events
+	 * in order to find the last seqnum
+	 *
+	 * This list is sorted.
+	 */
+	for (i = hotplug_queue_first; i != NULL; i = g_list_next (i)) {
 		msg = (struct hald_helper_msg *) i->data;
-		if (msg->seqnum < last_hotplug_seqnum)
-			last_hotplug_seqnum = msg->seqnum;
+		HAL_INFO (("*** msg->seqnum = %lld", msg->seqnum));
+		last_hotplug_seqnum = msg->seqnum;
 	}
-	--last_hotplug_seqnum;
 
-	HAL_INFO (("Starting with SEQNUM=%llu", last_hotplug_seqnum+1));
+	/* Done sleeping on the first hotplug event */
+	hotplug_sleep_first_event = FALSE;
+
+	HAL_INFO (("Starting with last_hotplug_seqnum=%llu", last_hotplug_seqnum));
 
 	hotplug_sem_down ();
 
@@ -1421,6 +1448,15 @@
 	return FALSE;
 }
 
+static gint
+hald_helper_msg_compare (gconstpointer pa, gconstpointer pb)
+{
+	const struct hald_helper_msg *a = (const struct hald_helper_msg *) pa;
+	const struct hald_helper_msg *b = (const struct hald_helper_msg *) pb;
+
+	return (gint) (a->seqnum - b->seqnum);
+}
+
 static gboolean
 hald_helper_data (GIOChannel *source, 
 		  GIOCondition condition, 
@@ -1489,26 +1525,50 @@
 			 * @todo TODO: read SEQNUM from sysfs
 			 */
 
-			HAL_WARNING (("First SEQNUM=%llu; sleeping 2500ms to get a few more events", msg.seqnum));
+			HAL_INFO (("First SEQNUM=%llu; sleeping %dms to get a few more events", 
+				   msg.seqnum, FIRST_HOTPLUG_SLEEP));
 
 			hotplug_sem_up ();
-			g_timeout_add (2500, hald_helper_first_hotplug_event, NULL);
+			g_timeout_add (FIRST_HOTPLUG_SLEEP, hald_helper_first_hotplug_event, NULL);
+			hotplug_sleep_first_event = TRUE;
+
+			hotplug_queue_first = g_list_insert_sorted (hotplug_queue_first, 
+								    g_memdup (&msg, sizeof (struct hald_helper_msg)),
+								    hald_helper_msg_compare);
 
 			/* so we only setup one timer */
 			last_hotplug_seqnum = msg.seqnum;
+
+			goto out;
 		}
 
-		if (msg.seqnum < last_hotplug_seqnum) {
+		/* If sleeping on the first hotplug event queue up the events in a special queue */
+		if (hotplug_sleep_first_event) {
+			HAL_INFO (("first hotplug sleep; got SEQNUM=%d", msg.seqnum));
+			hotplug_queue_first = g_list_insert_sorted (hotplug_queue_first, 
+								    g_memdup (&msg, sizeof (struct hald_helper_msg)),
+								    hald_helper_msg_compare);
+		} else {
 
-			/* Just reduce the last_hotplug_seqnum counter */
-			last_hotplug_seqnum = msg.seqnum;
-		}
+			if (msg.seqnum < last_hotplug_seqnum) {
+				/* yikes, this means were started during a hotplug */
+				HAL_WARNING (("Got SEQNUM=%llu, but last_hotplug_seqnum=%llu", 
+					      msg.seqnum, last_hotplug_seqnum));
+                                /* have to process immediately other we may deadlock due to the hotplug semaphore */
+				hald_helper_hotplug (msg.action, msg.seqnum, g_strdup (msg.subsystem), 	 
+						     g_strdup (msg.sysfs_path), &msg); 	 
+				/* still process the queue though */
+				hald_helper_hotplug_process_queue ();
 
-		/* Queue up this hotplug event and process the queue */
-		HAL_INFO (("Queing up seqnum=%llu, sysfspath=%s, subsys=%s", 
-			   msg.seqnum, msg.sysfs_path, msg.subsystem));
-		hotplug_queue = g_list_append (hotplug_queue, g_memdup (&msg, sizeof (struct hald_helper_msg)));
-		hald_helper_hotplug_process_queue ();
+			} else {
+				/* Queue up this hotplug event and process the queue */
+				HAL_INFO (("Queing up seqnum=%llu, sysfspath=%s, subsys=%s", 
+					   msg.seqnum, msg.sysfs_path, msg.subsystem));
+				hotplug_queue = g_list_append (hotplug_queue, 
+							       g_memdup (&msg, sizeof (struct hald_helper_msg)));
+				hald_helper_hotplug_process_queue ();
+			}
+		}
 		break;
 	}
 out:




More information about the hal-commit mailing list