summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-08-02 09:37:24 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-08-02 09:37:24 -0700
commit73a7ae605d364be49dc5bd1cc15c1116fe47a446 (patch)
tree752c37f24563565c8589cbacb05492df003b709c
parent404e5c4091c607a39d28b651063da9bdc7ebb3bb (diff)
downloadtxr-73a7ae605d364be49dc5bd1cc15c1116fe47a446.tar.gz
txr-73a7ae605d364be49dc5bd1cc15c1116fe47a446.tar.bz2
txr-73a7ae605d364be49dc5bd1cc15c1116fe47a446.zip
* signal.c (interrupt_count): New global variable.
(sig_handler): Increment and decrement interrupt count. If the interrupt count is already positive, treat that as if async signals were not enabled: do not invoke handlers.
-rw-r--r--ChangeLog8
-rw-r--r--signal.c6
2 files changed, 13 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index f577bad7..0bc6a437 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-08-02 Kaz Kylheku <kaz@kylheku.com>
+
+ * signal.c (interrupt_count): New global variable.
+ (sig_handler): Increment and decrement interrupt count.
+ If the interrupt count is already positive, treat
+ that as if async signals were not enabled: do not
+ invoke handlers.
+
2014-08-01 Kaz Kylheku <kaz@kylheku.com>
* configure (have_sys_time): New variable.
diff --git a/signal.c b/signal.c
index 35e55fa3..e900f536 100644
--- a/signal.c
+++ b/signal.c
@@ -46,6 +46,7 @@
#define MAX_SIG 32
volatile sig_atomic_t async_sig_enabled = 0;
+static volatile sig_atomic_t interrupt_count = 0;
sigset_t sig_blocked_cache;
static val sig_lambda[MAX_SIG];
@@ -69,6 +70,7 @@ static void sig_handler(int sig)
int gc = 0;
int as = 0;
int exc = is_cpu_exception(sig);
+ int in_interrupt = interrupt_count++ > 0;
if (exc) {
gc = gc_state(0);
@@ -77,7 +79,7 @@ static void sig_handler(int sig)
}
if (lambda) {
- if (async_sig_enabled) {
+ if (!in_interrupt && async_sig_enabled) {
async_sig_enabled = 0;
if (funcall2(lambda, num_fast(sig), t))
sig_deferred |= (1UL << sig);
@@ -91,6 +93,8 @@ static void sig_handler(int sig)
async_sig_enabled = as;
gc_state(gc);
}
+
+ interrupt_count--;
}
static val kill_wrap(val pid, val sig)