aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2015-06-30 11:53:34 +0200
committerErlang/OTP <[email protected]>2015-06-30 11:53:34 +0200
commitd8765c20ceb9dbb4f711e0b256cc201f5e422e77 (patch)
treedee46644b9677eb58ecb0c6333e10617e316fd6e
parent74a95b3d511177a9b35c2b0272b9ca5511b6f750 (diff)
parent7bbb207b30360c60fb9965359635e1cd0ad70c77 (diff)
downloadotp-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.c15
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;
}
/*