diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/posix/Signals.c | 17 |
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"); + } } } |