[PATCH] xfree86: Use SA_SIGINFO if available for SIGIO handlers
Adam Jackson
ajax at redhat.com
Tue Nov 10 12:03:31 PST 2009
This one's slightly subtle, the fcntl(F_SETSIG) is required for ->si_fd
to actually be filled in correctly, at least on Linux. I know this area
has been sensitive to platform variation in the past, so I'd appreciate
a second look from Solaris / BSD / Hurd people.
---
siginfo_t gives us the file descriptor that raised the signal directly,
so we don't need to select() for it. This gets evdev event processing
down to exactly one syscall in the common case.
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
hw/xfree86/os-support/shared/sigio.c | 40 ++++++++++++++++++++++++++++-----
1 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c
index aed5654..4f1ec55 100644
--- a/hw/xfree86/os-support/shared/sigio.c
+++ b/hw/xfree86/os-support/shared/sigio.c
@@ -95,12 +95,11 @@ static int xf86SigIOMax;
static int xf86SigIOMaxFd;
static fd_set xf86SigIOMask;
-/*
- * SIGIO gives no way of discovering which fd signalled, select
- * to discover
- */
+#ifndef SA_SIGINFO
+
+/* plain signals have no way of discovering which fd signalled. */
static void
-xf86SIGIO (int sig)
+sigio_handler (int sig)
{
int i;
fd_set ready;
@@ -126,6 +125,27 @@ xf86SIGIO (int sig)
errno = save_errno;
}
+#else /* have SA_SIGINFO */
+
+/* siginfo passes the triggering fd in, no need to select() */
+static void
+sigio_sigaction(int sig, siginfo_t *si, void *ctx)
+{
+ int i;
+ int save_errno = errno;
+
+ for (i = 0; i < MAX_FUNCS; i++) {
+ if (xf86SigIOFuncs[i].f && xf86SigIOFuncs[i].fd == si->si_fd) {
+ (*xf86SigIOFuncs[i].f)(si->si_fd, xf86SigIOFuncs[i].closure);
+ break;
+ }
+ }
+
+ errno = save_errno;
+}
+
+#endif
+
static int
xf86IsPipe (int fd)
{
@@ -164,6 +184,9 @@ xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *closure)
xf86Msg(X_WARNING, "fcntl(%d, F_SETOWN): %s\n",
fd, strerror(errno));
} else {
+#ifdef SA_SIGINFO
+ fcntl(fd, F_SETSIG, SIGIO);
+#endif
installed = TRUE;
}
}
@@ -184,8 +207,13 @@ xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *closure)
}
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO);
+#ifndef SA_SIGINFO
sa.sa_flags = 0;
- sa.sa_handler = xf86SIGIO;
+ sa.sa_handler = sigio_handler;
+#else
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigio_sigaction;
+#endif
sigaction(SIGIO, &sa, &osa);
xf86SigIOFuncs[i].fd = fd;
xf86SigIOFuncs[i].closure = closure;
--
1.6.5.2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
Url : http://lists.x.org/archives/xorg-devel/attachments/20091110/e292efe8/attachment.pgp
More information about the xorg-devel
mailing list