forked from pool/xorg-x11-server
291 lines
7.8 KiB
Diff
291 lines
7.8 KiB
Diff
|
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
|
||
|
|