--
Tiago Vignatti
C3SL - Centro de Computação Científica e Software Livre
www.c3sl.ufpr.br
>From 6414b27901b2d802ceb86b27adb066ff6f6357e5 Mon Sep 17 00:00:00 2001
From: Tiago Vignatti <[EMAIL PROTECTED]>
Date: Wed, 1 Oct 2008 21:18:07 -0300
Subject: [PATCH] dix implementation of the input-thread.

All stuff is wrapped by INPUT_THREAD macro. So is possible to use
--{disable, enable}-input-thread to {un,}set it. This is worth in the aspects
of debug (e.g. gdb is a really sh*t in multi-thread enviroments).

The input thread is enabled by default.

Signed-off-by: Tiago Vignatti <[EMAIL PROTECTED]>
---
 configure.ac            |    8 ++++++
 dix/main.c              |   11 +++++++++
 include/dix-config.h.in |    3 ++
 include/opaque.h        |    3 ++
 include/os.h            |   17 ++++++++++++++
 os/Makefile.am          |    7 +++++-
 os/WaitFor.c            |    8 ++++++
 os/connection.c         |   55 ++++++++++++++++++++++++++++++++++++++++++++++-
 8 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index d768546..05ae3cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -495,6 +495,9 @@ AC_ARG_ENABLE(builtin-fonts,  AS_HELP_STRING([--enable-builtin-fonts], [Use only
 AC_ARG_ENABLE(null-root-cursor, AS_HELP_STRING([--enable-null-root-cursor], [Use an empty root cursor (default: use core cursor)]),
                                  [NULL_ROOT_CURSOR=$enableval],
                                  [NULL_ROOT_CURSOR=no])
+AC_ARG_ENABLE(input-thread,  AS_HELP_STRING([--enable-input-thread], [Use a separate thread for input devices (default: yes)]),
+                                [INPUT_THREAD=$enableval],
+                                [INPUT_THREAD=yes])
 
 dnl GLX build options
 AC_ARG_WITH(mesa-source,     AS_HELP_STRING([--with-mesa-source=MESA_SOURCE], [Path to Mesa source tree]),
@@ -933,6 +936,11 @@ if test "x$BUILTIN_FONTS" = xyes; then
        FONTPATH="built-ins"
 fi
 
+AM_CONDITIONAL(INPUT_THREAD, [test "x$INPUT_THREAD" = xyes])
+if test "x$INPUT_THREAD" = xyes; then
+       AC_DEFINE(INPUT_THREAD, 1, [Use a separate thread for input devices])
+fi
+
 if test "x$XCALIBRATE" = xyes && test "$KDRIVE" = yes; then
    AC_DEFINE(XCALIBRATE, 1, [Build XCalibrate extension])
    REQUIRED_MODULES="$REQUIRED_MODULES xcalibrateproto"
diff --git a/dix/main.c b/dix/main.c
index 267aba5..ac8f010 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -281,6 +281,9 @@ int main(int argc, char *argv[], char *envp[])
         config_init();
 	if(serverGeneration == 1)
 	{
+#ifdef INPUT_THREAD
+        InitInputThread();
+#endif
 	    CreateWellKnownSockets();
 	    InitProcVectors();
 	    for (i=1; i<MAXCLIENTS; i++)
@@ -387,6 +390,10 @@ int main(int argc, char *argv[], char *envp[])
 
 	NotifyParentProcess();
 
+#ifdef INPUT_THREAD
+    CreateInputThread();
+#endif
+
 	Dispatch();
 
         UndisplayDevices();
@@ -414,6 +421,10 @@ int main(int argc, char *argv[], char *envp[])
 	CloseDownDevices();
 	CloseDownEvents();
 
+#ifdef INPUT_THREAD
+    CloseInputThread();
+#endif
+
 	for (i = screenInfo.numScreens - 1; i >= 0; i--)
 	{
 	    FreeScratchPixmapsForScreen(i);
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 06138c5..64c6f40 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -436,4 +436,7 @@
 /* Define to 1 if you have the `ffs' function. */
 #undef HAVE_FFS
 
+/* Define to 1 to use the input thread */
+#undef INPUT_THREAD
+
 #endif /* _DIX_CONFIG_H_ */
diff --git a/include/opaque.h b/include/opaque.h
index 07a0715..0ba1a10 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -36,6 +36,9 @@ from The Open Group.
 extern char *defaultTextFont;
 extern char *defaultCursorFont;
 extern int MaxClients;
+#ifdef INPUT_THREAD
+extern int MaxInputDevices;
+#endif
 extern volatile char isItTimeToYield;
 extern volatile char dispatchException;
 
diff --git a/include/os.h b/include/os.h
index bfe2363..26fc089 100644
--- a/include/os.h
+++ b/include/os.h
@@ -169,6 +169,23 @@ extern void MakeClientGrabPervious(ClientPtr /*client*/);
 extern void ListenOnOpenFD(int /* fd */, int /* noxauth */);
 #endif
 
+#ifdef INPUT_THREAD
+extern void InitInputThread(void);
+
+extern void CreateInputThread(void);
+
+extern void CloseInputThread(void);
+
+extern void AddEnabledDeviceThreaded(int /*fd*/, void (*f)(void *),
+                                     void *closure);
+
+extern void RemoveEnabledDeviceThreaded(int /*fd*/);
+
+extern int PipeRead(int /* fd */);
+
+extern void PipeWrite(int /* fd */);
+#endif
+
 extern void AvailableClientInput(ClientPtr /* client */);
 
 extern CARD32 GetTimeInMillis(void);
diff --git a/os/Makefile.am b/os/Makefile.am
index 16ecc15..5601d67 100644
--- a/os/Makefile.am
+++ b/os/Makefile.am
@@ -7,6 +7,10 @@ XDMCP_SRCS = xdmcp.c
 STRLCAT_SRCS = strlcat.c strlcpy.c
 XORG_SRCS = log.c
 
+if INPUT_THREAD
+INPUT_THREAD_SRC = inputthread.c
+endif
+
 libos_la_SOURCES = 	\
 	WaitFor.c	\
 	access.c	\
@@ -23,7 +27,8 @@ libos_la_SOURCES = 	\
 	xdmauth.c	\
 	xstrans.c	\
 	xprintf.c	\
-	$(XORG_SRCS)
+	$(XORG_SRCS) \
+	$(INPUT_THREAD_SRC)
 
 if SECURE_RPC
 libos_la_SOURCES += $(SECURERPC_SRCS)
diff --git a/os/WaitFor.c b/os/WaitFor.c
index d6dd995..5d2a361 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -125,6 +125,9 @@ static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
 static void CheckAllTimers(void);
 static OsTimerPtr timers = NULL;
 
+#ifdef INPUT_THREAD
+extern int MainThreadReadPipe;
+#endif
 /*****************
  * WaitForSomething:
  *     Make the server suspend until there is
@@ -225,6 +228,11 @@ WaitForSomething(int *pClientsReady)
 	}
 	else 
 	{
+#ifdef INPUT_THREAD
+        /* Empty the signaling pipe */
+        if (PipeRead(MainThreadReadPipe) > 0)
+            AddEnabledDevice(MainThreadReadPipe);
+#endif
 	    i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
 	}
 	selecterr = GetErrno();
diff --git a/os/connection.c b/os/connection.c
index a111fa5..4dba2e5 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -142,6 +142,9 @@ fd_set ClientsWithInput;	/* clients with FULL requests in buffer */
 fd_set ClientsWriteBlocked;	/* clients who cannot receive output */
 fd_set OutputPending;		/* clients with reply/event data ready to go */
 int MaxClients = 0;
+#ifdef INPUT_THREAD
+int MaxInputDevices = 0;
+#endif
 Bool NewOutputPending;		/* not yet attempted to write some new output */
 Bool AnyClientsWriteBlocked;	/* true if some client blocked on write */
 
@@ -302,7 +305,9 @@ InitConnectionLimits(void)
 
     if (lastfdesc > MAXSELECT)
 	lastfdesc = MAXSELECT;
-
+#ifdef INPUT_THREAD
+    MaxInputDevices = lastfdesc;
+#endif
     if (lastfdesc > MAXCLIENTS)
     {
 	lastfdesc = MAXCLIENTS;
@@ -1314,3 +1319,51 @@ _X_EXPORT void ListenOnOpenFD(int fd, int noxauth) {
 }
 
 #endif
+
+#ifdef INPUT_THREAD
+_X_EXPORT int
+PipeRead(int from)
+{
+    int array[10];
+
+    int ret = read(from, &array, sizeof(array));
+
+    if (ret >= 0) {
+        return ret;
+    }
+    if (errno != EAGAIN) {
+        FatalError("read: %d", errno);
+    }
+#if DEBUG
+    ErrorF("read waited at count\n");
+#endif
+    return 1;
+}
+
+_X_EXPORT void
+PipeWrite(int to)
+{
+    char    nullbyte = 0;
+    fd_set  wait;
+
+    FD_ZERO(&wait);
+    for (;;) {
+        int ret;
+
+        /* POSIX guarantees that this write is atomic */
+        ret = write(to, &nullbyte, 1);
+        if (!ret)
+            FatalError("Out of space?");
+        if (ret > 0) {
+            break;
+        }
+        if (errno != EAGAIN) 
+            FatalError("write");
+#if DEBUG
+        ErrorF(stderr, "write waiting\n");
+#endif
+        FD_SET(to, &wait);
+        select(to+1, NULL, &wait, NULL, NULL);
+    }
+}
+#endif /* INPUT_THREAD */
-- 
1.5.4.3

_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to