[PATCH v2] OS/ACPI: Retry (re)connecting to acpid until successful

Egbert Eich eich at freedesktop.org
Mon Sep 16 12:10:39 PDT 2013


On Linux the Xserver connects to the ACPI daemon to
receive power management events. If this daemon isn't
running when the Xserver starts or restarts while the
Xserver is active the connection is lost.
This adds a timer which periodically tries to (re)connect.

Signed-off-by: Egbert Eich <eich at freedesktop.org>
---
v2: Don't forget to set acpiTimer.
    Fixed description.

 hw/xfree86/os-support/linux/lnx_acpi.c | 66 +++++++++++++++++++++++++++-------
 hw/xfree86/os-support/linux/lnx_apm.c  |  9 +++++
 2 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index dcaa19e..7385869 100644
--- a/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -32,9 +32,12 @@
 #define ACPI_VIDEO_HEAD_INVALID		(~0u - 1)
 #define ACPI_VIDEO_HEAD_END		(~0u)
 
+static PMClose doLnxACPIOpen(void);
 static void lnxCloseACPI(void);
 static pointer ACPIihPtr = NULL;
+static OsTimerPtr acpiTimer = NULL;
 PMClose lnxACPIOpen(void);
+PMClose lnxACPIPoll(void);
 
 /* in milliseconds */
 #define ACPI_REOPEN_DELAY 1000
@@ -52,6 +55,18 @@ lnxACPIReopen(OsTimerPtr timer, CARD32 time, pointer arg)
 
 #define LINE_LENGTH 80
 
+static CARD32
+lnxACPICheckTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+    DebugF("ACPI: trying to reopen\n");
+    if (doLnxACPIOpen()) {
+        DebugF("ACPI: successfully reopened\n");
+        acpiTimer = NULL;
+        return 0;
+    }
+    return 10000;
+}
+
 static int
 lnxACPIGetEventFromOs(int fd, pmEvent * events, int num)
 {
@@ -66,7 +81,7 @@ lnxACPIGetEventFromOs(int fd, pmEvent * events, int num)
 
     if (n <= 0) {
         lnxCloseACPI();
-        TimerSet(NULL, 0, ACPI_REOPEN_DELAY, lnxACPIReopen, NULL);
+        acpiTimer = TimerSet(NULL, 0, ACPI_REOPEN_DELAY, lnxACPIReopen, NULL);
         return 0;
     }
     /* FIXME: this only processes the first read ACPI event & might break
@@ -130,33 +145,35 @@ lnxACPIConfirmEventToOs(int fd, pmEvent event)
     }
 }
 
-PMClose
-lnxACPIOpen(void)
+static PMClose
+doLnxACPIOpen(void)
 {
-    int fd;
+    int fd = -1;
     struct sockaddr_un addr;
     int r = -1;
     static int warned = 0;
 
-    DebugF("ACPI: OSPMOpen called\n");
     if (ACPIihPtr || !xf86Info.pmFlag)
         return NULL;
 
     DebugF("ACPI: Opening device\n");
-    if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) > -1) {
+    fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (fd > -1) {
         memset(&addr, 0, sizeof(addr));
         addr.sun_family = AF_UNIX;
         strcpy(addr.sun_path, ACPI_SOCKET);
-        if ((r = connect(fd, (struct sockaddr *) &addr, sizeof(addr))) == -1) {
-            if (!warned)
-                xf86MsgVerb(X_WARNING, 3, "Open ACPI failed (%s) (%s)\n",
+        r = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
+        if (r == -1) {
+            if (errno != warned)
+                xf86MsgVerb(X_WARNING,3,"Open ACPI failed (%s) (%s)\n",
                             ACPI_SOCKET, strerror(errno));
-            warned = 1;
-            shutdown(fd, 2);
+            warned = errno;
+            shutdown(fd, SHUT_RDWR);
             close(fd);
             return NULL;
         }
-    }
+    } else
+        return NULL;
 
     xf86PMGetEventFromOs = lnxACPIGetEventFromOs;
     xf86PMConfirmEventToOs = lnxACPIConfirmEventToOs;
@@ -167,6 +184,23 @@ lnxACPIOpen(void)
     return lnxCloseACPI;
 }
 
+PMClose
+lnxACPIPoll(void)
+{
+    TimerSet(NULL, 0, 10000, lnxACPICheckTimer, NULL);
+    return lnxCloseACPI;
+}
+
+PMClose
+lnxACPIOpen(void)
+{
+    PMClose ret;
+    DebugF("ACPI: OSPMOpen called\n");
+    ret = doLnxACPIOpen();
+
+    return ret;
+}
+
 static void
 lnxCloseACPI(void)
 {
@@ -175,8 +209,14 @@ lnxCloseACPI(void)
     DebugF("ACPI: Closing device\n");
     if (ACPIihPtr) {
         fd = xf86RemoveGeneralHandler(ACPIihPtr);
-        shutdown(fd, 2);
+        shutdown(fd, SHUT_RDWR);
         close(fd);
         ACPIihPtr = NULL;
+        xf86PMGetEventFromOs = NULL;
+        xf86PMConfirmEventToOs = NULL;
+        if (acpiTimer) {
+            TimerCancel(acpiTimer);
+            acpiTimer = NULL;
+        }
     }
 }
diff --git a/hw/xfree86/os-support/linux/lnx_apm.c b/hw/xfree86/os-support/linux/lnx_apm.c
index 3879340..2628f5c 100644
--- a/hw/xfree86/os-support/linux/lnx_apm.c
+++ b/hw/xfree86/os-support/linux/lnx_apm.c
@@ -12,6 +12,7 @@
 
 #ifdef HAVE_ACPI
 extern PMClose lnxACPIOpen(void);
+extern PMClose lnxACPIPoll(void);
 #endif
 
 #ifdef HAVE_APM
@@ -149,6 +150,14 @@ xf86OSPMOpen(void)
         ret = lnxAPMOpen();
 #endif
 
+#ifdef HAVE_ACPI
+    /* if we can neither open ACPI nor APM poll for an ACPI service to
+       become available */
+
+    if (!ret && !xf86acpiDisableFlag)
+	    ret = lnxACPIPoll();
+#endif
+
     return ret;
 }
 
-- 
1.8.1.4



More information about the xorg-devel mailing list