summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)