1
0
xorg-x11-server/u_OS-acpi-Reconnect-to-acpid-when-it-gets-restarted.patch

291 lines
7.8 KiB
Diff
Raw Normal View History

From 142ba992065dd9c37a9d06dc6e96cfc9adfb6be0 Mon Sep 17 00:00:00 2001
From: Egbert Eich <eich@suse.de>
Date: Tue, 5 Jul 2011 06:56:43 +0200
Subject: [PATCH] OS/acpi: Reconnect to acpid when it gets restarted.
Patch-mainline: To be upstreamed
On Linux the Xserver connects to the ACPI daemon to
receive power management events. If this daemon isn't
started when the server starts or goes down the connection
is lost.
When this happens we add a timer which periodically
tries to reconnect.
Signed-off-by: Egbert Eich <eich@suse.de>
---
hw/xfree86/os-support/linux/lnx_acpi.c | 68 ++++++++++++++++++++++++++-----
hw/xfree86/os-support/linux/lnx_apm.c | 9 ++++
2 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index 5fad194..8dd6881 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,22 @@ lnxACPIReopen(OsTimerPtr timer, CARD32 time, pointer arg)
#define LINE_LENGTH 80
+static CARD32
+lnxACPICheckTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+#if DEBUG
+ ErrorF("ACPI: trying to reopen\n");
+#endif
+ if (doLnxACPIOpen()) {
+#if DEBUG
+ ErrorF("ACPI: successfully reopened\n");
+#endif
+ acpiTimer = NULL;
+ return 0;
+ }
+ return 10000;
+}
+
static int
lnxACPIGetEventFromOs(int fd, pmEvent *events, int num)
{
@@ -127,33 +146,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)
+ 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;
@@ -164,6 +185,25 @@ lnxACPIOpen(void)
return lnxCloseACPI;
}
+PMClose
+lnxACPIPoll(void)
+{
+ TimerSet(NULL, 0, 10000, lnxACPICheckTimer, NULL);
+ return lnxCloseACPI;
+}
+
+PMClose
+lnxACPIOpen(void)
+{
+ PMClose ret;
+#ifdef DEBUG
+ ErrorF("ACPI: OSPMOpen called\n");
+#endif
+ ret = doLnxACPIOpen();
+
+ return ret;
+}
+
static void
lnxCloseACPI(void)
{
@@ -172,8 +212,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 54c6989..c8b254f 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.6.0.2
From 3f35d15f7c7eb202de36e2d1040f27ef7b38c1d2 Mon Sep 17 00:00:00 2001
From: Egbert Eich <eich@freedesktop.org>
Date: Thu, 7 Jul 2011 09:01:35 +0200
Subject: [PATCH] OS/ACPI: Make socket to read from acpid non-blocking.
If acpid for some reason does not service a connect() this
function may hang forever stalling the Xserver. To prevent
this make the socket non-blocking. If connect returns
EINPROGRESS use select() and getsockopt() to check for
completion of the connect request.
select() gets a different timeout depending if it is called
during startup or to do a reconnect.
Signed-off-by: Egbert Eich <eich@freedesktop.org>
---
hw/xfree86/os-support/linux/lnx_acpi.c | 34 +++++++++++++++++++++++++++----
1 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index 8dd6881..f0e6eb4 100644
--- a/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -32,7 +32,7 @@
#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
#define ACPI_VIDEO_HEAD_END (~0u)
-static PMClose doLnxACPIOpen(void);
+static PMClose doLnxACPIOpen(struct timeval *);
static void lnxCloseACPI(void);
static pointer ACPIihPtr = NULL;
static OsTimerPtr acpiTimer = NULL;
@@ -58,10 +58,11 @@ lnxACPIReopen(OsTimerPtr timer, CARD32 time, pointer arg)
static CARD32
lnxACPICheckTimer(OsTimerPtr timer, CARD32 now, pointer arg)
{
+ struct timeval timeval = { 0, 0 };
#if DEBUG
ErrorF("ACPI: trying to reopen\n");
#endif
- if (doLnxACPIOpen()) {
+ if (doLnxACPIOpen(&timeval)) {
#if DEBUG
ErrorF("ACPI: successfully reopened\n");
#endif
@@ -147,7 +148,7 @@ lnxACPIConfirmEventToOs(int fd, pmEvent event)
}
static PMClose
-doLnxACPIOpen(void)
+doLnxACPIOpen(struct timeval *tv_p)
{
int fd = -1;
struct sockaddr_un addr;
@@ -158,13 +159,34 @@ doLnxACPIOpen(void)
return NULL;
DebugF("ACPI: Opening device\n");
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
if (fd > -1) {
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, ACPI_SOCKET);
r = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
if (r == -1) {
+ int sock_errno = errno;
+ if (sock_errno == EINPROGRESS) {
+ fd_set fds;
+ int result;
+ do {
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ result = select(fd + 1, NULL, &fds, NULL, tv_p);
+ } while (result < 0 && errno == EINTR);
+ if (result < 0)
+ sock_errno = errno;
+ else if (result > 0) {
+ int sock_errno;
+ socklen_t size = sizeof(sock_errno);
+ if (0 > getsockopt(fd, SOL_SOCKET, SO_ERROR, &sock_errno,
+ &size))
+ sock_errno = errno;
+ if (!sock_errno)
+ goto success;
+ }
+ }
if (errno != warned)
xf86MsgVerb(X_WARNING,3,"Open ACPI failed (%s) (%s)\n",
ACPI_SOCKET, strerror(errno));
@@ -176,6 +198,7 @@ doLnxACPIOpen(void)
} else
return NULL;
+ success:
xf86PMGetEventFromOs = lnxACPIGetEventFromOs;
xf86PMConfirmEventToOs = lnxACPIConfirmEventToOs;
ACPIihPtr = xf86AddGeneralHandler(fd,xf86HandlePMEvents,NULL);
@@ -196,10 +219,11 @@ PMClose
lnxACPIOpen(void)
{
PMClose ret;
+ struct timeval timeval = { 0, 30000 };
#ifdef DEBUG
ErrorF("ACPI: OSPMOpen called\n");
#endif
- ret = doLnxACPIOpen();
+ ret = doLnxACPIOpen(&timeval);
return ret;
}
--
1.7.3.4