diff options
author | Erlang/OTP <[email protected]> | 2015-06-25 14:28:44 +0200 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2015-06-25 14:28:44 +0200 |
commit | 70a77207f03290bfff585b2e6e7930e411f6fa08 (patch) | |
tree | 34074224be2e10413cde74f9f78818f62486daa2 | |
parent | eb012e5d805c3d921186ceab32dd62374cb49981 (diff) | |
parent | 7bbb207b30360c60fb9965359635e1cd0ad70c77 (diff) | |
download | otp-70a77207f03290bfff585b2e6e7930e411f6fa08.tar.gz otp-70a77207f03290bfff585b2e6e7930e411f6fa08.tar.bz2 otp-70a77207f03290bfff585b2e6e7930e411f6fa08.zip |
Merge branch 'sverk/poll-lost-wakeup/OTP-12859' into maint-17
* 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 aa412a20c8..e798dc11b9 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; } /* |