b6b7852
From 645de09fc84482a55b5234312027efd007e53d8c Mon Sep 17 00:00:00 2001
b6b7852
From: Adam Jackson <ajax@redhat.com>
b6b7852
Date: Sat, 7 Nov 2009 15:29:05 -0500
b6b7852
Subject: [PATCH] xfree86: Use SA_SIGINFO if available for SIGIO handlers
b6b7852
b6b7852
siginfo_t gives us the file descriptor that raised the signal directly,
b6b7852
so we don't need to select() for it.  This gets evdev event processing
b6b7852
down to exactly one syscall in the common case.
b6b7852
b6b7852
Signed-off-by: Adam Jackson <ajax@redhat.com>
b6b7852
---
b6b7852
 hw/xfree86/os-support/shared/sigio.c |   40 ++++++++++++++++++++++++++++-----
b6b7852
 1 files changed, 34 insertions(+), 6 deletions(-)
b6b7852
b6b7852
diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c
b6b7852
index aed5654..4f1ec55 100644
b6b7852
--- a/hw/xfree86/os-support/shared/sigio.c
b6b7852
+++ b/hw/xfree86/os-support/shared/sigio.c
b6b7852
@@ -95,12 +95,11 @@ static int		xf86SigIOMax;
b6b7852
 static int		xf86SigIOMaxFd;
b6b7852
 static fd_set		xf86SigIOMask;
b6b7852
 
b6b7852
-/*
b6b7852
- * SIGIO gives no way of discovering which fd signalled, select
b6b7852
- * to discover
b6b7852
- */
b6b7852
+#ifndef SA_SIGINFO
b6b7852
+
b6b7852
+/* plain signals have no way of discovering which fd signalled. */
b6b7852
 static void
b6b7852
-xf86SIGIO (int sig)
b6b7852
+sigio_handler (int sig)
b6b7852
 {
b6b7852
     int	    i;
b6b7852
     fd_set  ready;
b6b7852
@@ -126,6 +125,27 @@ xf86SIGIO (int sig)
b6b7852
     errno = save_errno;
b6b7852
 }
b6b7852
 
b6b7852
+#else /* have SA_SIGINFO */
b6b7852
+
b6b7852
+/* siginfo passes the triggering fd in, no need to select() */
b6b7852
+static void
b6b7852
+sigio_sigaction(int sig, siginfo_t *si, void *ctx)
b6b7852
+{
b6b7852
+    int i;
b6b7852
+    int save_errno = errno;
b6b7852
+
b6b7852
+    for (i = 0; i < MAX_FUNCS; i++) {
b6b7852
+        if (xf86SigIOFuncs[i].f && xf86SigIOFuncs[i].fd == si->si_fd) {
b6b7852
+            (*xf86SigIOFuncs[i].f)(si->si_fd, xf86SigIOFuncs[i].closure);
b6b7852
+            break;
b6b7852
+        }
b6b7852
+    }
b6b7852
+
b6b7852
+    errno = save_errno;
b6b7852
+}
b6b7852
+
b6b7852
+#endif
b6b7852
+
b6b7852
 static int
b6b7852
 xf86IsPipe (int fd)
b6b7852
 {
b6b7852
@@ -164,6 +184,9 @@ xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *closure)
b6b7852
 		    xf86Msg(X_WARNING, "fcntl(%d, F_SETOWN): %s\n",
b6b7852
 			    fd, strerror(errno));
b6b7852
 		} else {
b6b7852
+#ifdef SA_SIGINFO
b6b7852
+                    fcntl(fd, F_SETSIG, SIGIO);
b6b7852
+#endif
b6b7852
 		    installed = TRUE;
b6b7852
 		}
b6b7852
 	    }
b6b7852
@@ -184,8 +207,13 @@ xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *closure)
b6b7852
 	    }
b6b7852
 	    sigemptyset(&sa.sa_mask);
b6b7852
 	    sigaddset(&sa.sa_mask, SIGIO);
b6b7852
+#ifndef SA_SIGINFO
b6b7852
 	    sa.sa_flags   = 0;
b6b7852
-	    sa.sa_handler = xf86SIGIO;
b6b7852
+	    sa.sa_handler = sigio_handler;
b6b7852
+#else
b6b7852
+            sa.sa_flags     = SA_SIGINFO;
b6b7852
+            sa.sa_sigaction = sigio_sigaction;
b6b7852
+#endif
b6b7852
 	    sigaction(SIGIO, &sa, &osa;;
b6b7852
 	    xf86SigIOFuncs[i].fd = fd;
b6b7852
 	    xf86SigIOFuncs[i].closure = closure;
b6b7852
-- 
b6b7852
1.6.5.rc2
b6b7852