summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Vignatti <tiago.vignatti@nokia.com>2010-07-11 23:41:22 +0300
committerTiago Vignatti <tiago.vignatti@nokia.com>2010-07-11 23:58:21 +0300
commit47eecd9550264894401619c5e347442ef3c1512b (patch)
tree447316d3a44e0a24ca669490da1e605f12afc14d
parent241b303db338456a439f74d932d28d2a893eb73e (diff)
xserver: inputthread: (FIXME)
Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com>
-rw-r--r--configure.ac9
-rw-r--r--dix/main.c8
-rw-r--r--include/dix-config.h.in3
-rw-r--r--include/opaque.h4
-rw-r--r--include/os.h10
-rw-r--r--mi/mieq.c2
-rw-r--r--os/Makefile.am5
-rw-r--r--os/WaitFor.c9
-rw-r--r--os/connection.c81
9 files changed, 130 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index b3b752ce2..1a1f673eb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -476,6 +476,10 @@ AC_ARG_ENABLE(unit-tests, AS_HELP_STRING([--enable-unit-tests],
AC_ARG_ENABLE(use-sigio-by-default, AS_HELP_STRING([--enable-use-sigio-by-default]
[Enable SIGIO input handlers by default (default: $USE_SIGIO_BY_DEFAULT)]),
[USE_SIGIO_BY_DEFAULT=$enableval], [])
+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])
AC_ARG_WITH(int10, AS_HELP_STRING([--with-int10=BACKEND], [int10 backend: vm86, x86emu or stub]),
[INT10="$withval"],
[INT10="$DEFAULT_INT10"])
@@ -1125,6 +1129,11 @@ if test "x$DPMSExtension" = xyes; then
AC_DEFINE(DPMSExtension, 1, [Support DPMS extension])
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 47a932f15..317d3ec28 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -288,6 +288,10 @@ int main(int argc, char *argv[], char *envp[])
NotifyParentProcess();
+#ifdef INPUT_THREAD
+ CreateInputThread();
+#endif
+
Dispatch();
UndisplayDevices();
@@ -316,6 +320,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 6a332642b..e25261b9b 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -435,6 +435,9 @@
/* Need the strcasestr function. */
#undef NEED_STRCASESTR
+/* Define to 1 to use the input thread */
+#undef INPUT_THREAD
+
/* Define to 1 if you have the `ffs' function. */
#undef HAVE_FFS
diff --git a/include/opaque.h b/include/opaque.h
index b3c7c70d6..2d6807fcb 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -39,6 +39,10 @@ extern _X_EXPORT int MaxClients;
extern _X_EXPORT volatile char isItTimeToYield;
extern _X_EXPORT volatile char dispatchException;
+#ifdef INPUT_THREAD
+extern int MaxInputDevices;
+#endif
+
/* bit values for dispatchException */
#define DE_RESET 1
#define DE_TERMINATE 2
diff --git a/include/os.h b/include/os.h
index efa202c6c..af64b9ebf 100644
--- a/include/os.h
+++ b/include/os.h
@@ -165,6 +165,16 @@ extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client*/);
extern void ListenOnOpenFD(int /* fd */, int /* noxauth */);
#endif
+#ifdef INPUT_THREAD
+extern void AddEnabledDeviceThreaded(int /* fd */,
+ void (*f)(void *),
+ void *closure);
+extern int PipeRead(int /* fd */);
+extern void PipeWrite(int /* fd */);
+extern void CreateInputThread(void);
+extern void CloseInputThread(void);
+#endif
+
extern _X_EXPORT CARD32 GetTimeInMillis(void);
extern _X_EXPORT void AdjustWaitForDelay(
diff --git a/mi/mieq.c b/mi/mieq.c
index 50aaf88b7..ecedbb354 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -79,7 +79,7 @@ typedef struct _EventQueue {
static EventQueueRec miEventQueue;
-#ifdef XQUARTZ
+#if defined XQUARTZ || INPUT_THREAD
#include <pthread.h>
static pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER;
diff --git a/os/Makefile.am b/os/Makefile.am
index 3e4f2c591..52a4494cd 100644
--- a/os/Makefile.am
+++ b/os/Makefile.am
@@ -5,6 +5,7 @@ AM_CFLAGS = $(DIX_CFLAGS) $(SHA1_CFLAGS)
SECURERPC_SRCS = rpcauth.c
XDMCP_SRCS = xdmcp.c
STRLCAT_SRCS = strlcat.c strlcpy.c
+INPUT_THREAD_SRCS = inputthread.c
# Build a convenience library liblog.la that will be added into
# libos.la. The split is done so that log.c can be built with
@@ -47,6 +48,10 @@ if NEED_STRLCAT
libos_la_SOURCES += $(STRLCAT_SRCS)
endif
+if INPUT_THREAD
+libos_la_SOURCES += $(INPUT_THREAD_SRCS)
+endif
+
EXTRA_DIST = $(SECURERPC_SRCS) $(INTERNALMALLOC_SRCS) \
$(XDMCP_SRCS) $(STRLCAT_SRCS)
diff --git a/os/WaitFor.c b/os/WaitFor.c
index e66300490..a50a487f4 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -126,6 +126,10 @@ static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
static void CheckAllTimers(void);
static OsTimerPtr timers = NULL;
+#ifdef INPUT_THREAD
+extern int InputThreadReadPipe;
+#endif
+
/*****************
* WaitForSomething:
* Make the server suspend until there is
@@ -226,6 +230,11 @@ WaitForSomething(int *pClientsReady)
}
else
{
+#ifdef INPUT_THREAD
+ /* Empty the signaling pipe */
+ if (PipeRead(InputThreadReadPipe) > 0)
+ AddEnabledDevice(InputThreadReadPipe);
+#endif
i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
}
selecterr = GetErrno();
diff --git a/os/connection.c b/os/connection.c
index c143fb6d3..8760c1256 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -145,6 +145,10 @@ int MaxClients = 0;
Bool NewOutputPending; /* not yet attempted to write some new output */
Bool AnyClientsWriteBlocked; /* true if some client blocked on write */
+#ifdef INPUT_THREAD
+int MaxInputDevices = 0;
+#endif
+
static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
Bool PartialNetwork; /* continue even if unable to bind all addrs */
static Pid_t ParentProcess;
@@ -158,6 +162,13 @@ static fd_set SavedAllSockets;
static fd_set SavedClientsWithInput;
int GrabInProgress = 0;
+#ifdef INPUT_THREAD
+fd_set InputThreadFd; /* Devices monitored by the input thread */
+int NumDevicesThreaded = 0; /* Number of devices in the input thread */
+int InputThreadReadPipe = -1;
+int InputThreadWritePipe = -1;
+#endif
+
#if !defined(WIN32)
int *ConnectionTranslation = NULL;
#else
@@ -302,6 +313,10 @@ InitConnectionLimits(void)
if (lastfdesc > MAXSELECT)
lastfdesc = MAXSELECT;
+#ifdef INPUT_THREAD
+ MaxInputDevices = lastfdesc;
+#endif
+
if (lastfdesc > MAXCLIENTS)
{
lastfdesc = MAXCLIENTS;
@@ -372,11 +387,34 @@ CreateWellKnownSockets(void)
int partial;
char port[20];
+#ifdef INPUT_THREAD
+ int tfd[2];
+#endif
+
FD_ZERO(&AllSockets);
FD_ZERO(&AllClients);
FD_ZERO(&LastSelectMask);
FD_ZERO(&ClientsWithInput);
+#ifdef INPUT_THREAD
+ /* The "communication channel" between the input and main thread */
+ if (pipe(tfd) < 0) {
+ perror("pipe");
+ exit(1);
+ }
+
+ /* Make the pipes nonblocking */
+ fcntl(tfd[0], F_SETFL, O_NONBLOCK);
+ fcntl(tfd[1], F_SETFL, O_NONBLOCK);
+
+ InputThreadReadPipe = tfd[0];
+ InputThreadWritePipe = tfd[1];
+
+ FD_ZERO(&InputThreadFd);
+
+ NumDevicesThreaded = 0;
+#endif
+
#if !defined(WIN32)
for (i=0; i<MaxClients; i++) ConnectionTranslation[i] = 0;
#else
@@ -1307,3 +1345,46 @@ 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);
+ }
+ DebugF("read waited at count\n");
+ 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");
+ DebugF(stderr, "write waiting\n");
+ FD_SET(to, &wait);
+ select(to+1, NULL, &wait, NULL, NULL);
+ }
+}
+#endif /* INPUT_THREAD */