diff options
author | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2017-01-03 00:44:35 +0000 |
---|---|---|
committer | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2017-01-03 01:02:41 +0000 |
commit | 91b2ee084430dbe5d81d32d15e06b53d931514d9 (patch) | |
tree | 4c4d8c97359280219b18f58a0d7623f05f0ae970 | |
parent | 1e7a92dac7fa412cc79eed3aa5db3050ed5b6b4c (diff) |
Block signals except during the event loop. Closes:#692233.
Previously we would interrupt whatever we were doing, willy-nilly.
Now we wait until the event loop is reentered. Symptoms could include
locking up the server with a grab, and/or spinning on the cpu.
This patch is not very portable (it uses ppoll) but I think it will
work on all Debian architectures.
In the longer term we should update to new upstream, where the last
commits were in 2013.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
-rw-r--r-- | debian/changelog | 1 | ||||
-rw-r--r-- | events.c | 48 | ||||
-rw-r--r-- | events.h | 4 | ||||
-rw-r--r-- | twm.c | 6 |
4 files changed, 58 insertions, 1 deletions
diff --git a/debian/changelog b/debian/changelog index 9acbb8b..b9b206a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,6 @@ vtwm (5.4.7-4~) unstable; urgency=medium + * Block signals during the event loop. Closes:#692233. * .gitignore: Add a .gitignore covering files outside debian/ generated by dpkg-buildpackage -uc -b on amd64. * .gitignore: Add a debian/.gitignore too. @@ -36,8 +36,12 @@ * ***********************************************************************/ +#define _GNU_SOURCE /* for ppoll */ #include <stdio.h> #include <string.h> +#include <signal.h> +#include <poll.h> +#include <errno.h> #include "twm.h" #include <X11/Xatom.h> #include "add_window.h" @@ -362,6 +366,35 @@ Bool DispatchEvent () /*********************************************************************** * + * Procedures: + * BlockSignalsAddToList required for every signal we handle + * BlockSignals } signals must be blocked except in + * UnBlockSignals } the relevant bit of the event loop + * + *********************************************************************** + */ + +static _Bool blocksignalslist_initialised; +static sigset_t blocksignalslist; + +void +BlockSignalsAddToList(sig) + int sig; +{ + if (!blocksignalslist_initialised++) + sigemptyset(&blocksignalslist); + + sigaddset(&blocksignalslist, sig); +} + +void +BlockSignals() +{ + sigprocmask(SIG_BLOCK, &blocksignalslist, NULL); +} + +/*********************************************************************** + * * Procedure: * HandleEvents - handle X events * @@ -371,6 +404,12 @@ Bool DispatchEvent () void HandleEvents() { + struct pollfd pfd; + pfd.fd = ConnectionNumber(dpy); + pfd.events = POLLIN|POLLPRI; + sigset_t emptyset; + sigemptyset(&emptyset); + while (TRUE) { if (enter_flag && !QLength(dpy)) { @@ -384,7 +423,14 @@ HandleEvents() InstallWindowColormaps(ColormapNotify, (TwmWindow *) NULL); } WindowMoved = FALSE; - XNextEvent(dpy, &Event); + while (!XCheckMaskEvent(dpy, -1 /* wot no AllEventMask */, &Event)) { + int r; + r = ppoll(&pfd, 1, 0, &emptyset); + if (r<0 && errno!=EINTR) { + perror("vtwm: poll failed"); + exit(-1); + } + } (void) DispatchEvent (); } } @@ -77,6 +77,10 @@ extern void InstallWindowColormaps(); extern void RedoDoorName(); /* djhjr - 2/28/99 */ extern void RedoListWindow(); /* djhjr - 3/1/99 */ +extern void BlockSignalsAddToList(); +extern void BlockSignals(); +extern void UnblockSignals(); + extern event_proc EventHandler[]; extern Window DragWindow; extern int origDragX; @@ -258,12 +258,15 @@ main(argc, argv, environ) /* djhjr - 6/22/01 */ #ifndef NO_SOUND_SUPPORT #define sounddonehandler(sig) \ + BlockSignalsAddToList(sig); \ if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, PlaySoundDone) #else #define sounddonehandler(sig) \ + BlockSignalsAddToList(sig); \ if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done) #endif #define donehandler(sig) \ + BlockSignalsAddToList(sig); \ if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done) sounddonehandler (SIGINT); @@ -282,8 +285,11 @@ main(argc, argv, environ) #undef donehandler /* djhjr - 7/31/98 */ + BlockSignalsAddToList(SIGUSR1); signal (SIGUSR1, QueueRestartVtwm); + BlockSignals(); + Home = getenv("HOME"); if (Home == NULL) Home = "./"; |