diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-09-06 22:46:46 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-09-06 22:46:46 -0700 |
commit | 1cabc4bd21295e92aff4776adebfb6f8c7a86f8b (patch) | |
tree | f1fe24677486d7bfcc39fa25fe8bb56122548a5f /signal.c | |
parent | ded0935f38e13b0b211c6a365277b26241325446 (diff) | |
download | txr-1cabc4bd21295e92aff4776adebfb6f8c7a86f8b.tar.gz txr-1cabc4bd21295e92aff4776adebfb6f8c7a86f8b.tar.bz2 txr-1cabc4bd21295e92aff4776adebfb6f8c7a86f8b.zip |
Manage intr count in the face of exceptions.
* signal.c (sig_handler): Make sure the interrupt_count
is restored to the value on entry into the handler
if the lambda throws.
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -75,7 +75,8 @@ static void sig_handler(int sig) int gc = 0; int as = 0; int exc = is_cpu_exception(sig); - int in_interrupt = interrupt_count++ > 0; + int ic = interrupt_count++; + int in_interrupt = ic > 0; if (exc) { gc = gc_state(0); @@ -87,10 +88,15 @@ static void sig_handler(int sig) if (lambda) { if (!in_interrupt && async_sig_enabled) { + uw_simple_catch_begin; async_sig_enabled = 0; if (funcall2(lambda, num_fast(sig), t)) sig_deferred |= (1UL << sig); + uw_unwind { + interrupt_count = ic; + } async_sig_enabled = 1; + uw_catch_end; } else { sig_deferred |= (1UL << sig); } @@ -101,7 +107,7 @@ static void sig_handler(int sig) gc_state(gc); } - interrupt_count--; + interrupt_count = ic; } static val kill_wrap(val pid, val sig) |