On Thu, Dec 17, 2015 at 04:11:39PM -0800, Keith Packard wrote: > The current SIGIO signal handler method, used at generation of input events, > has a bunch of oddities. This patch introduces an alternative way using a > thread, which is used to select()s all input device file descriptors.
drop the s after select() > A mutex was used to control the access to input structures by the main and > input > threads. Two pipes to emit alert events (such hotplug ones) and guarantee the > proper communication between them was also used. > > Co-authored-by: Fernando Carrijo <[email protected]> > Signed-off-by: Tiago Vignatti <[email protected]> > > v2: Fix non-Xorg link, and disable by default on non-Linux > > This also splits out the actual enabling of input threads to > DDX-specific patches which follow > > v3: Make the input lock recursive > > Signed-off-by: Adam Jackson <[email protected]> > Signed-off-by: Keith Packard <[email protected]> > > recursive lock > --- > configure.ac | 29 ++++ > dix/globals.c | 9 ++ > dix/main.c | 9 +- > hw/xfree86/sdksyms.sh | 4 + > include/input.h | 25 ++++ > include/misc.h | 1 + > mi/mieq.c | 38 +---- > os/Makefile.am | 1 + > os/inputthread.c | 379 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > os/utils.c | 9 +- > 10 files changed, 461 insertions(+), 43 deletions(-) > create mode 100644 os/inputthread.c > > diff --git a/configure.ac b/configure.ac > index 5a43db3..bc15581 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -821,6 +821,35 @@ SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO > $XEXTPROTO $INPUTPROTO $K > # Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc > AC_SUBST(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]) shouldn't this set InputThreadEnable as well? afaict right now it's always enabled, regardless what we say here (except that it'll probably fail the build since the libs are missing). > +if test "x$INPUTTHREAD" = "xyes" ; then > + case $host_os in > + linux*|openbsd*|gnu*|k*bsd*-gnu) > + THREAD_LIB=-lpthread ;; you're using quotes for the others but not here > + 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" > +fi > + > REQUIRED_MODULES="$FIXESPROTO $DAMAGEPROTO $XCMISCPROTO $XTRANS > $BIGREQSPROTO $SDK_REQUIRED_MODULES" > > dnl systemd socket activation > diff --git a/dix/globals.c b/dix/globals.c > index f36a938..e313930 100644 > --- a/dix/globals.c > +++ b/dix/globals.c > @@ -132,3 +132,12 @@ Bool explicit_display = FALSE; > char *ConnectionInfo; > > CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; > + > +#if DEBUG_INPUT_MUTEX > +#define INPUT_MUTEX_INITIALIZER PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP > +#else > +#define INPUT_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER > +#endif > + > +pthread_mutex_t input_mutex = INPUT_MUTEX_INITIALIZER; > +__thread int input_mutex_count; > diff --git a/dix/main.c b/dix/main.c > index 661ab03..1649e72 100644 > --- a/dix/main.c > +++ b/dix/main.c > @@ -121,12 +121,9 @@ Equipment Corporation. > extern void Dispatch(void); > > #ifdef XQUARTZ > -#include <pthread.h> > - > -BOOL serverRunning = FALSE; > +BOOL serverRunning; > pthread_mutex_t serverRunningMutex = PTHREAD_MUTEX_INITIALIZER; > pthread_cond_t serverRunningCond = PTHREAD_COND_INITIALIZER; > - > #endif > > int > @@ -296,6 +293,8 @@ dix_main(int argc, char *argv[], char *envp[]) > > NotifyParentProcess(); > > + InputThreadInit(); > + indentation > Dispatch(); > > #ifdef XQUARTZ > @@ -328,6 +327,8 @@ dix_main(int argc, char *argv[], char *envp[]) > > CloseInput(); > > + InputThreadFini(); > + > for (i = 0; i < screenInfo.numScreens; i++) > screenInfo.screens[i]->root = NullWindow; > > diff --git a/hw/xfree86/sdksyms.sh b/hw/xfree86/sdksyms.sh > index 5391b72..fb2eaa1 100755 > --- a/hw/xfree86/sdksyms.sh > +++ b/hw/xfree86/sdksyms.sh > @@ -344,6 +344,10 @@ BEGIN { > n = 1; > } > > + if ($n ~ /__thread/) { > + next; > + } > + > # skip attribute, if any > while ($n ~ /^(__attribute__|__global)/ || > # skip modifiers, if any > diff --git a/include/input.h b/include/input.h > index 75887b7..01ea4d9 100644 > --- a/include/input.h > +++ b/include/input.h > @@ -56,6 +56,7 @@ SOFTWARE. > #include "xkbrules.h" > #include "events.h" > #include "list.h" > +#include "os.h" > #include <X11/extensions/XI2.h> > > #define DEVICE_INIT 0 > @@ -712,13 +713,37 @@ extern _X_HIDDEN void > input_constrain_cursor(DeviceIntPtr pDev, ScreenPtr screen > int *out_x, int *out_y, > int *nevents, InternalEvent* > events); > > +extern _X_EXPORT pthread_mutex_t input_mutex; > +extern _X_EXPORT __thread int input_mutex_count; > + > static inline void input_lock(void) { > + if (input_mutex_count++ == 0) > + pthread_mutex_lock(&input_mutex); > } > > static inline void input_unlock(void) { > + if (--input_mutex_count == 0) > + pthread_mutex_unlock(&input_mutex); > + assert(input_mutex_count >= 0); > } > > static inline void input_force_unlock(void) { > + if (input_mutex_count > 0) { > + input_mutex_count = 0; > + pthread_mutex_unlock(&input_mutex); > + } > } > > +extern void InputThreadPreInit(void); > +extern void InputThreadInit(void); > +extern void InputThreadFini(void); > + > +extern int InputThreadRegisterDev(int fd, > + NotifyFdProcPtr readInputProc, > + void *readInputArgs); > + > +extern int InputThreadUnregisterDev(int fd); > + > +extern _X_EXPORT Bool InputThreadEnable; > + > #endif /* INPUT_H */ > diff --git a/include/misc.h b/include/misc.h > index 56e138c..006f768 100644 > --- a/include/misc.h > +++ b/include/misc.h > @@ -79,6 +79,7 @@ OF THIS SOFTWARE. > > #include <stddef.h> > #include <stdint.h> > +#include <pthread.h> > > #ifndef MAXSCREENS > #define MAXSCREENS 16 > diff --git a/mi/mieq.c b/mi/mieq.c > index 8fbe6c3..8a67213 100644 > --- a/mi/mieq.c > +++ b/mi/mieq.c > @@ -88,9 +88,6 @@ typedef struct _EventQueue { > static EventQueueRec miEventQueue; > > #ifdef XQUARTZ > -#include <pthread.h> > -static pthread_mutex_t miEventQueueMutex = PTHREAD_MUTEX_INITIALIZER; > - > extern BOOL serverRunning; > extern pthread_mutex_t serverRunningMutex; > extern pthread_cond_t serverRunningCond; > @@ -252,7 +249,6 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) > > #ifdef XQUARTZ > wait_for_server_init(); > - pthread_mutex_lock(&miEventQueueMutex); > #endif > > verify_internal_event(e); > @@ -296,9 +292,6 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) > xorg_backtrace(); > } > > -#ifdef XQUARTZ > - pthread_mutex_unlock(&miEventQueueMutex); > -#endif > return; > } > > @@ -319,9 +312,6 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) > > miEventQueue.lastMotion = isMotion; > miEventQueue.tail = (oldtail + 1) % miEventQueue.nevents; > -#ifdef XQUARTZ > - pthread_mutex_unlock(&miEventQueueMutex); > -#endif > } > > /** > @@ -342,31 +332,19 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e) > void > mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool > set_dequeue_screen) > { > -#ifdef XQUARTZ > - pthread_mutex_lock(&miEventQueueMutex); > -#endif > EnqueueScreen(pDev) = pScreen; > if (set_dequeue_screen) > DequeueScreen(pDev) = pScreen; > -#ifdef XQUARTZ > - pthread_mutex_unlock(&miEventQueueMutex); > -#endif > } > > void > mieqSetHandler(int event, mieqHandler handler) > { > -#ifdef XQUARTZ > - pthread_mutex_lock(&miEventQueueMutex); > -#endif > if (handler && miEventQueue.handlers[event]) > ErrorF("[mi] mieq: warning: overriding existing handler %p with %p > for " > "event %d\n", miEventQueue.handlers[event], handler, event); > > miEventQueue.handlers[event] = handler; > -#ifdef XQUARTZ > - pthread_mutex_unlock(&miEventQueueMutex); > -#endif > } > > /** > @@ -581,9 +559,7 @@ mieqProcessInputEvents(void) > size_t n_enqueued; > static Bool inProcessInputEvents = FALSE; > > -#ifdef XQUARTZ > - pthread_mutex_lock(&miEventQueueMutex); > -#endif > + input_lock(); > > /* > * report an error if mieqProcessInputEvents() is called recursively; > @@ -621,9 +597,7 @@ mieqProcessInputEvents(void) > > miEventQueue.head = (miEventQueue.head + 1) % miEventQueue.nevents; > > -#ifdef XQUARTZ > - pthread_mutex_unlock(&miEventQueueMutex); > -#endif > + input_unlock(); > > master = (dev) ? GetMaster(dev, MASTER_ATTACHED) : NULL; > > @@ -647,14 +621,10 @@ mieqProcessInputEvents(void) > event.device_event.flags & TOUCH_POINTER_EMULATED))) > miPointerUpdateSprite(dev); > > -#ifdef XQUARTZ > - pthread_mutex_lock(&miEventQueueMutex); > -#endif > + input_lock(); > } > > inProcessInputEvents = FALSE; > > -#ifdef XQUARTZ > - pthread_mutex_unlock(&miEventQueueMutex); > -#endif > + input_unlock(); > } > diff --git a/os/Makefile.am b/os/Makefile.am > index a1bbb4d..fc49a73 100644 > --- a/os/Makefile.am > +++ b/os/Makefile.am > @@ -14,6 +14,7 @@ libos_la_SOURCES = \ > backtrace.c \ > client.c \ > connection.c \ > + inputthread.c \ > io.c \ > mitauth.c \ > oscolor.c \ > diff --git a/os/inputthread.c b/os/inputthread.c > new file mode 100644 > index 0000000..7c87e87 > --- /dev/null > +++ b/os/inputthread.c > @@ -0,0 +1,379 @@ > +/* inputthread.c -- Threaded generation of input events. > + * > + * Copyright © 2007-2008 Tiago Vignatti <vignatti at freedesktop org> > + * Copyright © 2010 Nokia > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: Fernando Carrijo <fcarrijo at freedesktop org> > + * Tiago Vignatti <vignatti at freedesktop org> > + */ > + > +#ifdef HAVE_DIX_CONFIG_H > +#include <dix-config.h> > +#endif > + > +#include <stdio.h> > +#include <errno.h> > +#include <stdlib.h> > +#include <unistd.h> > +#include <pthread.h> > + > +#include <X11/Xpoll.h> > +#include "inputstr.h" > +#include "opaque.h" > +#include "osdep.h" > + > +Bool InputThreadEnable = TRUE; > + > +/** > + * An input device as seen by the threaded input facility > + */ > +typedef struct _InputThreadDevice { > + struct xorg_list list; I'd rename that to 'node' rather than list, to make it more obvious that this is not a list head. > + NotifyFdProcPtr readInputProc; > + void *readInputArgs; > + int fd; > +} InputThreadDevice; > + > +/** > + * The threaded input facility. > + * > + * For now, we have one instance for all input devices. > + */ > +typedef struct { > + pthread_t thread; > + struct xorg_list devs; > + fd_set fds; > + int readPipe; > + int writePipe; > +} InputThreadInfo; > + > +static InputThreadInfo *inputThreadInfo; > + > +static int hotplugPipeRead = -1; > +static int hotplugPipeWrite = -1; > + > +/** > + * Notify a thread about the availability of new asynchronously enqueued > input > + * events. > + * > + * @see WaitForSomething() > + */ > +static void > +InputThreadFillPipe(int writeHead) > +{ > + int ret; > + char byte = 0; > + fd_set writePipe; > + > + FD_ZERO(&writePipe); > + > + while (1) { > + ret = write(writeHead, &byte, 1); > + if (!ret) > + FatalError("input-thread: write() returned 0"); > + if (ret > 0) { > + break; > + } drop the {} > + if (errno != EAGAIN) > + FatalError("input-thread: filling pipe"); > + > + DebugF("input-thread: pipe full\n"); > + FD_SET(writeHead, &writePipe); > + Select(writeHead + 1, NULL, &writePipe, NULL, NULL); > + } > +} > + > +/** > + * Consume eventual notifications left by a thread. > + * > + * @see WaitForSomething() > + * @see InputThreadFillPipe() > + */ > +static int > +InputThreadReadPipe(int readHead) > +{ > + int ret, array[10]; > + > + ret = read(readHead, &array, sizeof(array)); > + if (ret >= 0) > + return ret; > + > + if (errno != EAGAIN) > + FatalError("input-thread: draining pipe (%d)", errno); > + > + return 1; > +} > + > +/** > + * Register an input device in the threaded input facility > + * > + * @param fd File descriptor which identifies the input device > + * @param readInputProc Procedure used to read input from the device > + * @param readInputArgs Arguments to be consumed by the above procedure > + * > + * return 1 if success; 0 otherwise. > + */ > +int > +InputThreadRegisterDev(int fd, > + NotifyFdProcPtr readInputProc, > + void *readInputArgs) > +{ > + InputThreadDevice *new; urgh, can we use "dev" or "new_device" here, rather than just "new"? > + > + if (!inputThreadInfo) > + return SetNotifyFd(fd, readInputProc, X_NOTIFY_READ, readInputArgs); > + > + new = calloc(1, sizeof(InputThreadDevice)); > + if (new == NULL) { > + DebugF("input-thread: could not register device\n"); > + return 0; > + } > + > + new->fd = fd; > + new->readInputProc = readInputProc; > + new->readInputArgs = readInputArgs; > + > + xorg_list_add(&new->list, &inputThreadInfo->devs); > + > + FD_SET(fd, &inputThreadInfo->fds); > + > + InputThreadFillPipe(hotplugPipeWrite); > + DebugF("input-thread: registered device %d\n", fd); > + > + return 1; > +} > + > +/** > + * Unregister a device in the threaded input facility > + * > + * @param fd File descriptor which identifies the input device > + * > + * @return 1 if success; 0 otherwise. > + */ > +int > +InputThreadUnregisterDev(int fd) > +{ > + InputThreadDevice *dev; > + > + /* return silently if input thread is already finished (e.g., at > + * DisableDevice time, evdev tries to call this function again through > + * xf86RemoveEnabledDevice */ missing a closing ) > + if (!inputThreadInfo) { > + RemoveNotifyFd(fd); > + return 1; > + } > + > + xorg_list_for_each_entry(dev, &inputThreadInfo->devs, list) > + if (dev->fd == fd) > + break; > + > + /* fd didn't match any registered device. */ > + if (&dev->list == &inputThreadInfo->devs) > + return 0; use a boolean "found_device" or so here, much nicer to grasp than the list pointer comparison. > + > + xorg_list_del(&dev->list); > + > + FD_CLR(fd, &inputThreadInfo->fds); > + free(dev); > + > + InputThreadFillPipe(hotplugPipeWrite); > + DebugF("input-thread: unregistered device: %d\n", fd); > + > + return 1; > +} > + > +/** > + * The workhorse of threaded input event generation. > + * > + * Or if you prefer: The WaitForSomething for input devices. :) > + * > + * Runs in parallel with the server main thread, listening to input devices > in > + * an endless loop. Whenever new input data is made available, calls the > + * proper device driver's routines which are ultimately responsible for the > + * generation of input events. > + * > + * @see InputThreadPreInit() > + * @see InputThreadInit() > + */ > + > +static void* > +InputThreadDoWork(void *arg) > +{ > + fd_set readyFds; > + InputThreadDevice *dev, *next; > + > + FD_ZERO(&readyFds); > + > + while (1) > + { > + XFD_COPYSET(&inputThreadInfo->fds, &readyFds); > + FD_SET(hotplugPipeRead, &readyFds); > + > + DebugF("input-thread: InputThreadDoWork waiting for devices\n"); > + > + if (Select(MAXSELECT, &readyFds, NULL, NULL, NULL) < 0) { > + if (errno == EINVAL) > + FatalError("input-thread: InputThreadDoWork (%s)", > strerror(errno)); > + else if (errno != EINTR) > + ErrorF("input-thread: InputThreadDoWork (%s)\n", > strerror(errno)); > + } > + > + DebugF("input-thread: InputThreadDoWork generating events\n"); __func__ for all three? > + > + /* Call the device drivers to generate input events for us */ > + xorg_list_for_each_entry_safe(dev, next, &inputThreadInfo->devs, > list) > + if (FD_ISSET(dev->fd, &readyFds) && dev->readInputProc) { > + input_lock(); > + dev->readInputProc(dev->fd, X_NOTIFY_READ, > dev->readInputArgs); > + input_unlock(); > + } please wrap the xorg_list loop in { } Cheers, Peter > + > + /* Kick main thread to process the generated input events and drain > + * events from hotplug pipe */ > + InputThreadFillPipe(inputThreadInfo->writePipe); > + > + /* Empty pending input, shut down if the pipe has been closed */ > + if (FD_ISSET(hotplugPipeRead, &readyFds)) { > + if (InputThreadReadPipe(hotplugPipeRead) == 0) > + break; > + } > + } > + return NULL; > +} > + > +static void > +InputThreadNotifyPipe(int fd, int mask, void *data) > +{ > + InputThreadReadPipe(fd); > +} > + > +/** > + * Pre-initialize the facility used for threaded generation of input events > + * > + */ > +void > +InputThreadPreInit(void) > +{ > + int fds[2], hotplugPipe[2]; > + > + if (!InputThreadEnable) > + return; > + > + if (pipe(fds) < 0) > + FatalError("input-thread: could not create pipe"); > + > + if (pipe(hotplugPipe) < 0) > + FatalError("input-thread: could not create pipe"); > + > + inputThreadInfo = malloc(sizeof(InputThreadInfo)); > + if (!inputThreadInfo) > + FatalError("input-thread: could not allocate memory"); > + > + inputThreadInfo->thread = 0; > + xorg_list_init(&inputThreadInfo->devs); > + FD_ZERO(&inputThreadInfo->fds); > + > + /* By making read head non-blocking, we ensure that while the main thread > + * is busy servicing client requests, the dedicated input thread can work > + * in parallel. > + */ > + inputThreadInfo->readPipe = fds[0]; > + fcntl(inputThreadInfo->readPipe, F_SETFL, O_NONBLOCK | O_CLOEXEC); > + SetNotifyFd(inputThreadInfo->readPipe, InputThreadNotifyPipe, > X_NOTIFY_READ, NULL); > + > + inputThreadInfo->writePipe = fds[1]; > + > + hotplugPipeRead = hotplugPipe[0]; > + fcntl(hotplugPipeRead, F_SETFL, O_NONBLOCK | O_CLOEXEC); > + hotplugPipeWrite = hotplugPipe[1]; > +} > + > +/** > + * Start the threaded generation of input events. This routine complements > what > + * was previously done by InputThreadPreInit(), being only responsible for > + * creating the dedicated input thread. > + * > + */ > +void > +InputThreadInit(void) > +{ > + pthread_attr_t attr; > + > + /* If the driver hasn't asked for input thread support by calling > + * InputThreadPreInit, then do nothing here > + */ > + if (!inputThreadInfo) > + return; > + > + pthread_attr_init(&attr); > + > + /* For OSes that differentiate between processes and threads, the > following > + * lines have sense. Linux uses the 1:1 thread model. The scheduler > handles > + * every thread as a normal process. Therefore this probably has no > meaning > + * if we are under Linux. > + */ > + if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) != 0) > + ErrorF("input-thread: error setting thread scope\n"); > + > + DebugF("input-thread: creating thread\n"); > + pthread_create(&inputThreadInfo->thread, &attr, > + &InputThreadDoWork, NULL); > + > + pthread_attr_destroy (&attr); > +} > + > +/** > + * Stop the threaded generation of input events > + * > + * This function is supposed to be called at server shutdown time only. > + */ > +void > +InputThreadFini(void) > +{ > + InputThreadDevice *dev, *next; > + > + if (!inputThreadInfo) > + return; > + > + /* Close the pipe to get the input thread to shut down */ > + close(hotplugPipeWrite); > + pthread_join(inputThreadInfo->thread, NULL); > + > + xorg_list_for_each_entry_safe(dev, next, &inputThreadInfo->devs, list) { > + FD_CLR(dev->fd, &inputThreadInfo->fds); > + free(dev); > + } > + xorg_list_init(&inputThreadInfo->devs); > + FD_ZERO(&inputThreadInfo->fds); > + > + RemoveNotifyFd(inputThreadInfo->readPipe); > + close(inputThreadInfo->readPipe); > + close(inputThreadInfo->writePipe); > + inputThreadInfo->readPipe = -1; > + inputThreadInfo->writePipe = -1; > + > + close(hotplugPipeRead); > + hotplugPipeRead = -1; > + hotplugPipeWrite = -1; > + > + free(inputThreadInfo); > + inputThreadInfo = NULL; > +} > diff --git a/os/utils.c b/os/utils.c > index 7e8891d..c20ddfd 100644 > --- a/os/utils.c > +++ b/os/utils.c > @@ -586,7 +586,7 @@ UseMsg(void) > ErrorF("-xinerama Disable XINERAMA extension\n"); > #endif > ErrorF > - ("-dumbSched Disable smart scheduling, enable old > behavior\n"); > + ("-dumbSched Disable smart scheduling and threaded > input, enable old behavior\n"); > ErrorF("-schedInterval int Set scheduler interval in msec\n"); > ErrorF("-sigstop Enable SIGSTOP based startup\n"); > ErrorF("+extension name Enable extension\n"); > @@ -1004,11 +1004,12 @@ ProcessCommandLine(int argc, char *argv[]) > i = skip - 1; > } > #endif > -#if HAVE_SETITIMER > else if (strcmp(argv[i], "-dumbSched") == 0) { > + InputThreadEnable = FALSE; > +#if HAVE_SETITIMER > SmartScheduleSignalEnable = FALSE; > - } > #endif > + } > else if (strcmp(argv[i], "-schedInterval") == 0) { > if (++i < argc) { > SmartScheduleInterval = atoi(argv[i]); > @@ -1304,7 +1305,6 @@ OsBlockSignals(void) > if (BlockedSignalCount++ == 0) { > sigset_t set; > > - input_lock(); > sigemptyset(&set); > sigaddset(&set, SIGALRM); > sigaddset(&set, SIGVTALRM); > @@ -1326,7 +1326,6 @@ OsReleaseSignals(void) > #ifdef SIG_BLOCK > if (--BlockedSignalCount == 0) { > sigprocmask(SIG_SETMASK, &PreviousSignalMask, 0); > - input_unlock(); > } > #endif > } > -- > 2.6.4 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel > _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
