This is a possible solution for the problem reported in the
"xorg server should wait HAL if it's not avail during init"
thread.

  In my tests, it worked when running this:

% sudo service haldaemon stop; startx -- -verbose 3

  After waiting all the timeouts, it loaded kbd and mouse
drivers, and I had a usable desktop (I don't use gnome/kde).

  And also worked when running:

% startx -- -verbose 3 & sleep 5; sudo service haldaemon start

  After a few "timeouts" it managed to connect to hal and
"just worked" as expected.

  Maybe the timeouts should be configurable, etc. But consider
this, a "beta" patch :-)

  (The attached patch doesn't include the "trivial" changes
required to compile today's git master).

Thanks,
Paulo
>From 83a9866fc806a72740e5c0c81009e4220316765d Mon Sep 17 00:00:00 2001
From: Paulo Cesar Pereira de Andrade <p...@mandriva.com.br>
Date: Tue, 20 Jan 2009 19:36:59 -0200
Subject: [PATCH] Add hal/dbus fallback when not able to talk to hal/dbus daemons.

  hal/dbus may not be yet initialized in a "fast boot" where the
X Server may be started before some system daemons, or one may
choose to just not run the haldaemon service.
  This patch adds code to attempt connection with hal after 1, 2,
4, 8, 16 and 32 seconds. If hald is not available after that period,
it will load the "kbd" and "mouse" drivers, and FatalError() if
cannot load either.

  Details when adding different implementations, or changes to
this patch:

o libhal_ctx_set_cache() must be called, or it will never notice if
  hald has been started.
o if you set check info->system_bus to NULL, make sure you set it
  to the proper value again, when retrying to connect to hald.
---
 config/hal.c |   93 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 85 insertions(+), 8 deletions(-)

diff --git a/config/hal.c b/config/hal.c
index 8dfbb07..c7207d7 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -47,6 +47,9 @@
 struct config_hal_info {
     DBusConnection *system_bus;
     LibHalContext *hal_ctx;
+    OsTimerPtr timer;
+    int timeout;
+    Bool giveup;
 };
 
 /* Used for special handling of xkb options. */
@@ -58,6 +61,14 @@ struct xkb_options {
     char* options;
 };
 
+static int
+hal_connect(struct config_hal_info *info);
+
+static CARD32
+hal_connect_timer(OsTimerPtr timer, CARD32 time, pointer arg);
+
+static void
+hal_giveup(void);
 
 static void
 remove_device(DeviceIntPtr dev)
@@ -467,16 +478,13 @@ disconnect_hook(void *data)
     info->system_bus = NULL;
 }
 
-static void
-connect_hook(DBusConnection *connection, void *data)
+static int
+hal_connect(struct config_hal_info *info)
 {
     DBusError error;
-    struct config_hal_info *info = data;
     char **devices;
     int num_devices, i;
 
-    info->system_bus = connection;
-
     dbus_error_init(&error);
 
     if (!info->hal_ctx)
@@ -485,6 +493,7 @@ connect_hook(DBusConnection *connection, void *data)
         LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n");
         goto out_err;
     }
+    libhal_ctx_set_cache(info->hal_ctx, FALSE);
 
     if (!libhal_ctx_set_dbus_connection(info->hal_ctx, info->system_bus)) {
         LogMessage(X_ERROR, "config/hal: couldn't associate HAL context with bus\n");
@@ -512,7 +521,7 @@ connect_hook(DBusConnection *connection, void *data)
 
     dbus_error_free(&error);
 
-    return;
+    return 0;
 
 out_ctx2:
     if (!libhal_ctx_shutdown(info->hal_ctx, &error))
@@ -524,9 +533,77 @@ out_err:
     dbus_error_free(&error);
 
     info->hal_ctx = NULL;
-    info->system_bus = NULL;
 
-    return;
+    return 1;
+}
+
+static CARD32
+hal_connect_timer(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+    struct config_hal_info *info = (struct config_hal_info *)arg;
+
+    if (hal_connect(info) == 0) {
+	TimerFree(info->timer);
+	info->timer = NULL;
+    }
+    else {
+	info->timeout <<= 1;
+	if (info->timeout < 64) {
+	    LogMessage(X_WARNING, "config/hal: retrying in %d seconds\n",
+		       info->timeout);
+
+	    return (info->timeout * 1000);
+	}
+	else {
+	    LogMessage(X_ERROR, "config/hal: using fallbacks\n");
+	    if (!info->giveup)
+		hal_giveup();
+	    info->giveup = TRUE;
+	}
+    }
+
+    return (0);
+}
+
+static void
+hal_giveup(void)
+{
+    DeviceIntPtr dev;
+    InputOption *options;
+
+    options = NULL;
+    /* Or add another interface to tell it to enable this device */
+    add_option(&options, "_source", "server/hal");
+    add_option(&options, "driver", "kbd");
+    add_option(&options, "identifier", "kbd");
+    if (NewInputDeviceRequest(options, &dev) != Success)
+	FatalError("Failed to add a core keyboard\n");
+
+    options = NULL;
+    /* Or add another interface to tell it to enable this device */
+    add_option(&options, "_source", "server/hal");
+    add_option(&options, "driver", "mouse");
+    add_option(&options, "identifier", "mouse");
+    add_option(&options, "device", "/dev/input/mice");
+    if (NewInputDeviceRequest(options, &dev) != Success)
+	FatalError("Failed to add a core pointer\n");
+}
+
+static void
+connect_hook(DBusConnection *connection, void *data)
+{
+    struct config_hal_info *info = data;
+
+    info->system_bus = connection;
+    if (hal_connect(info) != 0) {
+	info->timeout = 1;
+	LogMessage(X_WARNING, "config/hal: retrying in %d seconds\n",
+		   info->timeout);
+	if (info->timer)
+	    TimerFree(info->timer);
+ 	info->timer = TimerSet(NULL, 0, info->timeout * 1000,
+			       hal_connect_timer, info);
+    }
 }
 
 static struct config_hal_info hal_info;
-- 
1.6.0.5
_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to