From ab3ce1cc13153b2053302cdb710cb411b0b9d84e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 29 Mar 2016 15:08:24 +0200 Subject: Improve SIGINT handling in multi-threaded programs The flag remembering whether an Interrupted exception was thrown is now thread-local. Thus, all threads will (eventually) throw Interrupted. Previously, one thread would throw Interrupted, and then the other threads wouldn't see that they were supposed to quit. --- src/libutil/util.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/libutil/util.cc') diff --git a/src/libutil/util.cc b/src/libutil/util.cc index d4ac3fb603..55d4909921 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1062,13 +1062,15 @@ void restoreSIGPIPE() volatile sig_atomic_t _isInterrupted = 0; +thread_local bool interruptThrown = false; + void _interrupted() { /* Block user interrupts while an exception is being handled. Throwing an exception while another exception is being handled kills the program! */ - if (!std::uncaught_exception()) { - _isInterrupted = 0; + if (!interruptThrown && !std::uncaught_exception()) { + interruptThrown = true; throw Interrupted("interrupted by the user"); } } -- cgit 1.4.1