summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
Diffstat (limited to 'rts')
-rw-r--r--rts/posix/Signals.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c
index 5fbb917cf8..a2fa07f091 100644
--- a/rts/posix/Signals.c
+++ b/rts/posix/Signals.c
@@ -126,7 +126,7 @@ more_handlers(int sig)
}
// Here's the pipe into which we will send our signals
-static int io_manager_wakeup_fd = -1;
+static volatile int io_manager_wakeup_fd = -1;
static int timer_manager_control_wr_fd = -1;
#define IO_MANAGER_WAKEUP 0xff
@@ -161,7 +161,20 @@ ioManagerWakeup (void)
StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
r = write(io_manager_wakeup_fd, &byte, 1);
#endif
- if (r == -1) { sysErrorBelch("ioManagerWakeup: write"); }
+ /* N.B. If the TimerManager is shutting down as we run this
+ * then there is a possiblity that our first read of
+ * io_manager_wakeup_fd is non-negative, but before we get to the
+ * write the file is closed. If this occurs, io_manager_wakeup_fd
+ * will be written into with -1 (GHC.Event.Control does this prior
+ * to closing), so checking this allows us to distinguish this case.
+ * To ensure we observe the correct ordering, we declare the
+ * io_manager_wakeup_fd as volatile.
+ * Since this is not an error condition, we do not print the error
+ * message in this case.
+ */
+ if (r == -1 && io_manager_wakeup_fd >= 0) {
+ sysErrorBelch("ioManagerWakeup: write");
+ }
}
}