diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-08-24 04:49:40 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2019-08-24 04:49:40 -0400 |
commit | 69678007cc4347ab9e198ed43aa952adbfe65fc4 (patch) | |
tree | 85d208a61e7dc2668b5a57b6d07aee7ef10117cd | |
parent | 47e162374051ed3e874ed7916cc811df288cbd95 (diff) | |
download | haskell-wip/T17090.tar.gz |
rts: Make event manager wakeup logic ThreadSanitizer-cleanwip/T17090
See #17090.
-rw-r--r-- | rts/posix/Signals.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index f8bd9fb829..51a46d6aa3 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -128,7 +128,7 @@ more_handlers(int sig) } // Here's the pipe into which we will send our signals -static volatile int io_manager_wakeup_fd = -1; +static int io_manager_wakeup_fd = -1; static int timer_manager_control_wr_fd = -1; #define IO_MANAGER_WAKEUP 0xff @@ -145,6 +145,7 @@ setIOManagerWakeupFd (int fd) // only called when THREADED_RTS, but unconditionally // compiled here because GHC.Event.Control depends on it. io_manager_wakeup_fd = fd; + write_barrier(); } /* ----------------------------------------------------------------------------- @@ -163,19 +164,24 @@ ioManagerWakeup (void) StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP; r = write(io_manager_wakeup_fd, &byte, 1); #endif + /* N.B. If the TimerManager is shutting down as we run this * then there is a possibility 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. + * To ensure we observe the correct ordering, we place a load-load + * barrier. 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"); + if (r == -1) { + load_load_barrier(); + if (io_manager_wakeup_fd >= 0) { + sysErrorBelch("ioManagerWakeup: write"); + } else { + /* the fd has been closed, this is okay as we are shutting down. */ + } } } } |