[PATCH] OS/ACPI: Reconnect to acpid when it gets restarted
Egbert Eich
eich at freedesktop.org
Wed Aug 14 09:19:21 PDT 2013
On Linux the Xserver connects to the ACPI daemon to
receive power management events. If this daemon isn't
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>
---
hw/xfree86/os-support/linux/lnx_acpi.c | 64 +++++++++++++++++++++++++++-------
hw/xfree86/os-support/linux/lnx_apm.c | 9 +++++
2 files changed, 61 insertions(+), 12 deletions(-)
diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index dcaa19e..52cc708 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)
{
@@ -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