diff options
author | Erlang/OTP <[email protected]> | 2015-06-30 11:53:34 +0200 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2015-06-30 11:53:34 +0200 |
commit | d8765c20ceb9dbb4f711e0b256cc201f5e422e77 (patch) | |
tree | dee46644b9677eb58ecb0c6333e10617e316fd6e | |
parent | 74a95b3d511177a9b35c2b0272b9ca5511b6f750 (diff) | |
parent | 7bbb207b30360c60fb9965359635e1cd0ad70c77 (diff) | |
download | otp-d8765c20ceb9dbb4f711e0b256cc201f5e422e77.tar.gz otp-d8765c20ceb9dbb4f711e0b256cc201f5e422e77.tar.bz2 otp-d8765c20ceb9dbb4f711e0b256cc201f5e422e77.zip |
Merge branch 'sverk/poll-lost-wakeup/OTP-12859' into maint-18
* sverk/poll-lost-wakeup/OTP-12859:
erts: Fix race in poller thread wake up
-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 884c403da4..21fa214364 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -431,7 +431,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; @@ -442,7 +442,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, @@ -469,14 +469,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; } /* |