From: Tiago Vignatti tiago.vigna...@nokia.com
If configured, and enabled at runtime, use a separate thread for
handling input devices. Use pipes to communicate plug events from main
thread to input thread, and to communicate event queue updates from
input thread to main thread.
For the xfree86 DDX, change the SIGIO handler to simply raise enough of
a dispatch exception to make the main loop interrupt request processing
and return to input processing. This has no effect when the input
thread is active but is a minor optimization when it's not.
v2:
- Fix memory leak in InputThreadUnregisterDev
- Fix build with --disable-input-thread
- Merge SIGIO strength reduction
Co-authored-by: Fernando Carrijo fcarr...@freedesktop.org
Signed-off-by: Tiago Vignatti tiago.vigna...@nokia.com
Signed-off-by: Adam Jackson a...@redhat.com
---
configure.ac | 30 +++
dix/main.c |3 +
hw/xfree86/common/xf86Events.c | 35 ++--
hw/xfree86/common/xf86Init.c |6 +-
include/Makefile.am|1 +
include/dix-config.h.in|3 +
include/inputthread.h | 36
include/opaque.h |2 +
mi/mieq.c | 76
os/Makefile.am |1 +
os/connection.c|4 +
os/inputthread.c | 404
12 files changed, 540 insertions(+), 61 deletions(-)
create mode 100644 include/inputthread.h
create mode 100644 os/inputthread.c
diff --git a/configure.ac b/configure.ac
index a80a13f..b516456 100644
--- a/configure.ac
+++ b/configure.ac
@@ -819,6 +819,36 @@ REQUIRED_LIBS=$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau
REQUIRED_MODULES=[fixesproto = 4.1] [damageproto = 1.1] [xcmiscproto =
1.2.0] [xtrans = 1.2.2] [bigreqsproto = 1.1.0] $SDK_REQUIRED_MODULES
+# input thread setup
+case $host_os in
+linux*)
+ THREAD_DEFAULT=yes ;;
+*)
+ THREAD_DEFAULT=no ;;
+esac
+AC_ARG_ENABLE(input-thread, AS_HELP_STRING([--enable-input-thread],
+[Enable input threads]),
+[INPUTTHREAD=$enableval], [INPUTTHREAD=$THREAD_DEFAULT])
+if test x$INPUTTHREAD = xyes ; then
+case $host_os in
+linux*|openbsd*|gnu*|k*bsd*-gnu)
+ THREAD_LIB=-lpthread ;;
+netbsd*)
+ THREAD_CFLAGS=-D_POSIX_THREAD_SAFE_FUNCTIONS
+ THREAD_LIB=-lpthread ;;
+freebsd*)
+ THREAD_CFLAGS=-D_THREAD_SAFE
+ THREAD_LIB=-pthread ;;
+dragonfly*)
+ THREAD_LIB=-pthread ;;
+solaris*)
+ THREAD_CFLAGS=-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS ;;
+esac
+SYS_LIBS=$SYS_LIBS $THREAD_LIB
+CFLAGS=$CFLAGS $THREAD_CFLAGS
+AC_DEFINE(USE_INPUT_THREAD, 1, [Use pthreads for input processing])
+fi
+
if test x$CONFIG_UDEV = xyes
{ test x$CONFIG_DBUS_API = xyes || test x$CONFIG_HAL = xyes; }; then
AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not
allowed])
diff --git a/dix/main.c b/dix/main.c
index 692bec1..8056892 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -99,6 +99,7 @@ Equipment Corporation.
#include opaque.h
#include servermd.h
#include hotplug.h
+#include inputthread.h
#include site.h
#include dixfont.h
#include extnsionst.h
@@ -284,6 +285,8 @@ int main(int argc, char *argv[], char *envp[])
NotifyParentProcess();
+ InputThreadInit();
+
Dispatch();
UndisplayDevices();
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 6561292..670addb 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -71,6 +71,7 @@
#include X11/extensions/XI.h
#include X11/extensions/XIproto.h
#include inputstr.h
+#include inputthread.h
#include xf86Xinput.h
#include mi.h
@@ -285,42 +286,36 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask)
if (xf86VTSwitchPending()) xf86VTSwitch();
}
-
/*
- * xf86SigioReadInput --
- *signal handler for the SIGIO signal.
+ * The host OS may or may not have working SIGIO handlers. If they don't,
+ * then the time_to_yield callback never gets called, and input will simply
+ * run out of the main loop whenever it gets around to it.
*/
+
static void
-xf86SigioReadInput(int fd, void *closure)
+time_to_yield(int fd, void *closure)
{
-int errno_save = errno;
-InputInfoPtr pInfo = closure;
-
-pInfo-read_input(pInfo);
-
-errno = errno_save;
+isItTimeToYield = 1;
}
-/*
- * xf86AddEnabledDevice --
- *
- */
void
xf86AddEnabledDevice(InputInfoPtr pInfo)
{
-if (!xf86InstallSIGIOHandler (pInfo-fd, xf86SigioReadInput, pInfo)) {
+if (!xf86silkenMouseDisableFlag) {
+ InputThreadRegisterDev(pInfo-fd, (void*) pInfo-read_input, pInfo);
+} else {
+ xf86InstallSIGIOHandler(pInfo-fd, time_to_yield, NULL);
AddEnabledDevice(pInfo-fd);
}
}
-/*
- * xf86RemoveEnabledDevice --
- *
- */
void
xf86RemoveEnabledDevice(InputInfoPtr pInfo)
{
-if