From: Ian Jackson Date: Tue, 3 Jan 2017 00:44:35 +0000 (+0000) Subject: Block signals except during the event loop. Closes:#692233. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=91b2ee084430dbe5d81d32d15e06b53d931514d9;p=vtwm.git 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 --- 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. diff --git a/events.c b/events.c index 28e1e29..7e8c7af 100644 --- a/events.c +++ b/events.c @@ -36,8 +36,12 @@ * ***********************************************************************/ +#define _GNU_SOURCE /* for ppoll */ #include #include +#include +#include +#include #include "twm.h" #include #include "add_window.h" @@ -360,6 +364,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: @@ -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 (); } } diff --git a/events.h b/events.h index 8d42304..6c447df 100644 --- a/events.h +++ b/events.h @@ -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; diff --git a/twm.c b/twm.c index 1402eee..edb040a 100644 --- a/twm.c +++ b/twm.c @@ -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 = "./";