diff options
author | Sverker Eriksson <[email protected]> | 2015-06-22 22:11:16 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2015-06-22 22:12:04 +0200 |
commit | 7bbb207b30360c60fb9965359635e1cd0ad70c77 (patch) | |
tree | be272702ec75c0389e3e2a9e4f6d0976b96c73dc /erts | |
parent | 23790daf1a2d384b0fc11c655fa825151d9fa420 (diff) | |
download | otp-7bbb207b30360c60fb9965359635e1cd0ad70c77.tar.gz otp-7bbb207b30360c60fb9965359635e1cd0ad70c77.tar.bz2 otp-7bbb207b30360c60fb9965359635e1cd0ad70c77.zip |
erts: Fix race in poller thread wake up
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/sys/common/erl_poll.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 0a58a625b2..4ac02d21d3 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -410,7 +410,7 @@ static ERTS_INLINE int is_interrupted_reset(ErtsPollSet ps) { #if defined(USE_THREADS) || ERTS_POLL_ASYNC_INTERRUPT_SUPPORT - return (erts_atomic32_xchg_nob(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN) + return (erts_atomic32_xchg_acqb(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN) == ERTS_POLL_WOKEN_INTR); #else return 0; @@ -421,7 +421,7 @@ static ERTS_INLINE void woke_up(ErtsPollSet ps) { #if defined(USE_THREADS) || ERTS_POLL_ASYNC_INTERRUPT_SUPPORT - erts_aint32_t wakeup_state = erts_atomic32_read_nob(&ps->wakeup_state); + erts_aint32_t wakeup_state = erts_atomic32_read_acqb(&ps->wakeup_state); if (wakeup_state == ERTS_POLL_NOT_WOKEN) (void) erts_atomic32_cmpxchg_nob(&ps->wakeup_state, ERTS_POLL_WOKEN, @@ -448,14 +448,9 @@ wake_poller(ErtsPollSet ps, int interrupted, int async_signal_safe) wakeup_state = erts_atomic32_cmpxchg_relb(&ps->wakeup_state, ERTS_POLL_WOKEN, ERTS_POLL_NOT_WOKEN); - else { - /* - * We might unnecessarily write to the pipe, however, - * that isn't problematic. - */ - wakeup_state = erts_atomic32_read_nob(&ps->wakeup_state); - erts_atomic32_set_relb(&ps->wakeup_state, ERTS_POLL_WOKEN_INTR); - } + else + wakeup_state = erts_atomic32_xchg_relb(&ps->wakeup_state, + ERTS_POLL_WOKEN_INTR); wake = wakeup_state == ERTS_POLL_NOT_WOKEN; } /* |