diff --git a/configure.ac b/configure.ac index c728d3007..6c96de2c3 100644 --- a/configure.ac +++ b/configure.ac @@ -832,6 +832,25 @@ 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) +AC_CHECK_DECL([PTHREAD_MUTEX_RECURSIVE], [HAVE_RECURSIVE_MUTEX=yes], [HAVE_RECURSIVE_MUTEX=no], [[#include ]]) + +THREAD_DEFAULT=no + +if test "x$HAVE_RECURSIVE_MUTEX" = "xyes" ; then + THREAD_DEFAULT=yes +fi + +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 + AX_PTHREAD(,AC_MSG_ERROR([threaded input requested but no pthread support has been found])) + SYS_LIBS="$SYS_LIBS $PTHREAD_LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + AC_DEFINE(INPUTTHREAD, 1, [Use a separate input thread]) +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 f36a938f7..e3139303f 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 77e0f2ecb..4ba43133e 100644 --- a/dix/main.c +++ b/dix/main.c @@ -121,12 +121,9 @@ Equipment Corporation. extern void Dispatch(void); #ifdef XQUARTZ -#include - -BOOL serverRunning = FALSE; +BOOL serverRunning; pthread_mutex_t serverRunningMutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t serverRunningCond = PTHREAD_COND_INITIALIZER; - #endif CallbackListPtr RootWindowFinalizeCallback = NULL; @@ -299,6 +296,8 @@ dix_main(int argc, char *argv[], char *envp[]) NotifyParentProcess(); + InputThreadInit(); + Dispatch(); #ifdef XQUARTZ @@ -331,6 +330,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/dmx/input/dmxsigio.c b/hw/dmx/input/dmxsigio.c index 6ef543c8b..ebfd3d98c 100644 --- a/hw/dmx/input/dmxsigio.c +++ b/hw/dmx/input/dmxsigio.c @@ -99,7 +99,7 @@ dmxSigioHook(void) sigaction(SIGIO, &a, 0); sigemptyset(&s); - sigprocmask(SIG_SETMASK, &s, 0); + xthread_sigmask(SIG_SETMASK, &s, 0); } static void diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c index e0cd7a89c..37d35f7e8 100644 --- a/hw/xfree86/os-support/shared/sigio.c +++ b/hw/xfree86/os-support/shared/sigio.c @@ -137,7 +137,7 @@ xf86BlockSIGIO(void) sigemptyset(&set); sigaddset(&set, SIGIO); - sigprocmask(SIG_BLOCK, &set, NULL); + xthread_sigmask(SIG_BLOCK, &set, NULL); } static void @@ -147,7 +147,7 @@ xf86ReleaseSIGIO(void) sigemptyset(&set); sigaddset(&set, SIGIO); - sigprocmask(SIG_UNBLOCK, &set, NULL); + xthread_sigmask(SIG_UNBLOCK, &set, NULL); } int diff --git a/include/dix-config.h.in b/include/dix-config.h.in index a164c15b5..fc7d1a12c 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -524,4 +524,7 @@ /* Have posix_fallocate() */ #undef HAVE_POSIX_FALLOCATE +/* Use input thread */ +#undef INPUTTHREAD + #endif /* _DIX_CONFIG_H_ */ diff --git a/include/input.h b/include/input.h index 9069a1cb5..e0f6b9b01 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 #define DEVICE_INIT 0 @@ -714,13 +715,20 @@ extern _X_HIDDEN void input_constrain_cursor(DeviceIntPtr pDev, ScreenPtr screen int *out_x, int *out_y, int *nevents, InternalEvent* events); -static inline void input_lock(void) { -} +extern _X_EXPORT void input_lock(void); +extern _X_EXPORT void input_unlock(void); +extern _X_EXPORT void input_force_unlock(void); -static inline void input_unlock(void) { -} +extern void InputThreadPreInit(void); +extern void InputThreadInit(void); +extern void InputThreadFini(void); -static inline void input_force_unlock(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 56e138c6b..006f76822 100644 --- a/include/misc.h +++ b/include/misc.h @@ -79,6 +79,7 @@ OF THIS SOFTWARE. #include #include +#include #ifndef MAXSCREENS #define MAXSCREENS 16 diff --git a/include/os.h b/include/os.h index e9b3709a1..20224f127 100644 --- a/include/os.h +++ b/include/os.h @@ -706,4 +706,9 @@ xorg_backtrace(void); extern _X_EXPORT int os_move_fd(int fd); +#include + +extern _X_EXPORT int +xthread_sigmask(int how, const sigset_t *set, sigset_t *oldest); + #endif /* OS_H */ diff --git a/mi/mieq.c b/mi/mieq.c index 8fbe6c363..8a6721304 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -88,9 +88,6 @@ typedef struct _EventQueue { static EventQueueRec miEventQueue; #ifdef XQUARTZ -#include -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 a1bbb4d1e..fc49a73e3 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 000000000..b6bbf3509 --- /dev/null +++ b/os/inputthread.c @@ -0,0 +1,470 @@ +/* inputthread.c -- Threaded generation of input events. + * + * Copyright © 2007-2008 Tiago Vignatti + * 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 + * Tiago Vignatti + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include "inputstr.h" +#include "opaque.h" +#include "osdep.h" + +#if INPUTTHREAD + +Bool InputThreadEnable = TRUE; + +/** + * An input device as seen by the threaded input facility + */ +typedef struct _InputThreadDevice { + struct xorg_list node; + 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; + +static int input_mutex_count; + +#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +static pthread_mutex_t input_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +#else +static pthread_mutex_t input_mutex; +static Bool input_mutex_initialized; +#endif + +void +input_lock(void) +{ +#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP + if (!input_mutex_initialized) { + pthread_mutexattr_t mutex_attr; + + input_mutex_initialized = TRUE; + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&input_mutex, &mutex_attr); + } +#endif + pthread_mutex_lock(&input_mutex); + ++input_mutex_count; +} + +void +input_unlock(void) +{ + --input_mutex_count; + pthread_mutex_unlock(&input_mutex); +} + +void +input_force_unlock(void) +{ + if (pthread_mutex_trylock(&input_mutex) == 0) { + /* unlock +1 times for the trylock */ + while (input_mutex_count-- >= 0) + pthread_mutex_unlock(&input_mutex); + } +} + +/** + * 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; + + 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 *dev; + + if (!inputThreadInfo) + return SetNotifyFd(fd, readInputProc, X_NOTIFY_READ, readInputArgs); + + dev = calloc(1, sizeof(InputThreadDevice)); + if (dev == NULL) { + DebugF("input-thread: could not register device\n"); + return 0; + } + + dev->fd = fd; + dev->readInputProc = readInputProc; + dev->readInputArgs = readInputArgs; + + xorg_list_add(&dev->node, &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; + Bool found_device = FALSE; + + /* return silently if input thread is already finished (e.g., at + * DisableDevice time, evdev tries to call this function again through + * xf86RemoveEnabledDevice) */ + if (!inputThreadInfo) { + RemoveNotifyFd(fd); + return 1; + } + + xorg_list_for_each_entry(dev, &inputThreadInfo->devs, node) + if (dev->fd == fd) { + found_device = TRUE; + break; + } + + /* fd didn't match any registered device. */ + if (!found_device) + return 0; + + xorg_list_del(&dev->node); + + 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; + sigset_t set; + + /* Don't handle any signals on this thread */ + sigfillset(&set); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + FD_ZERO(&readyFds); + + while (1) + { + XFD_COPYSET(&inputThreadInfo->fds, &readyFds); + FD_SET(hotplugPipeRead, &readyFds); + + DebugF("input-thread: %s waiting for devices\n", __func__); + + if (Select(MAXSELECT, &readyFds, NULL, NULL, NULL) < 0) { + if (errno == EINVAL) + FatalError("input-thread: %s (%s)", __func__, strerror(errno)); + else if (errno != EINTR) + ErrorF("input-thread: %s (%s)\n", __func__, strerror(errno)); + } + + DebugF("input-thread: %s generating events\n", __func__); + + /* Call the device drivers to generate input events for us */ + xorg_list_for_each_entry_safe(dev, next, &inputThreadInfo->devs, node) { + if (FD_ISSET(dev->fd, &readyFds) && dev->readInputProc) { + input_lock(); + dev->readInputProc(dev->fd, X_NOTIFY_READ, dev->readInputArgs); + input_unlock(); + } + } + + /* 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, node) { + 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; +} + +int xthread_sigmask(int how, const sigset_t *set, sigset_t *oldset) +{ + return pthread_sigmask(how, set, oldset); +} + +#else /* INPUTTHREAD */ + +Bool InputThreadEnable = FALSE; + +void input_lock(void) {} +void input_unlock(void) {} +void input_force_unlock(void) {} + +void InputThreadPreInit(void) {} +void InputThreadInit(void) {} +void InputThreadFini(void) {} + +int InputThreadRegisterDev(int fd, + NotifyFdProcPtr readInputProc, + void *readInputArgs) +{ + return SetNotifyFd(fd, readInputProc, X_NOTIFY_READ, readInputArgs); +} + +extern int InputThreadUnregisterDev(int fd) +{ + RemoveNotifyFd(fd); + return 1; +} + +int xthread_sigmask(int how, const sigset_t *set, sigset_t *oldset) +{ + return sigprocmask(how, set, oldset); +} + +#endif diff --git a/os/utils.c b/os/utils.c index db875c148..b5c5c5d28 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); @@ -1315,7 +1315,7 @@ OsBlockSignals(void) sigaddset(&set, SIGTTIN); sigaddset(&set, SIGTTOU); sigaddset(&set, SIGCHLD); - sigprocmask(SIG_BLOCK, &set, &PreviousSignalMask); + xthread_sigmask(SIG_BLOCK, &set, &PreviousSignalMask); } #endif } @@ -1325,8 +1325,7 @@ OsReleaseSignals(void) { #ifdef SIG_BLOCK if (--BlockedSignalCount == 0) { - sigprocmask(SIG_SETMASK, &PreviousSignalMask, 0); - input_unlock(); + xthread_sigmask(SIG_SETMASK, &PreviousSignalMask, 0); } #endif }