about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-29 07:34:13 +0000
committerbors <bors@rust-lang.org>2018-06-29 07:34:13 +0000
commit2eb6969c6a2efba9e59544bc18b4d96a9f2b2504 (patch)
tree939c603efdcec98b3c4178d30c0dc3dc92a26b31 /src/libstd
parent3b50455c61847c4a417b5fb002a5258dbaf4a868 (diff)
parentb352d2d167f1de4ed8a6da3405dc90fe9d646204 (diff)
downloadrust-2eb6969c6a2efba9e59544bc18b4d96a9f2b2504.tar.gz
rust-2eb6969c6a2efba9e59544bc18b4d96a9f2b2504.zip
Auto merge of #51290 - Pslydhh:master, r=alexcrichton
park/park_timeout: prohibit spurious wakeups in next park

<pre><code>
// The implementation currently uses the trivial strategy of a Mutex+Condvar
// with wakeup flag, which does not actually allow spurious wakeups.
</pre></code>

Because does not actually allow spurious wakeups.
so we have let thread.inner.cvar.wait(m) in the loop to prohibit spurious wakeups.
but if notified after we locked, this notification doesn't be consumed, it return, the next park will consume this notification...this is also 'spurious wakeup' case, 'one unpark() wakeups two  park()'.

We should improve this situation:
`thread.inner.state.store(EMPTY, SeqCst);`
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/thread/mod.rs10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 1dacf99b64b..90f054186d1 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -796,7 +796,10 @@ pub fn park() {
     let mut m = thread.inner.lock.lock().unwrap();
     match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
         Ok(_) => {}
-        Err(NOTIFIED) => return, // notified after we locked
+        Err(NOTIFIED) => {
+            thread.inner.state.store(EMPTY, SeqCst);
+            return;
+        } // should consume this notification, so prohibit spurious wakeups in next park.
         Err(_) => panic!("inconsistent park state"),
     }
     loop {
@@ -882,7 +885,10 @@ pub fn park_timeout(dur: Duration) {
     let m = thread.inner.lock.lock().unwrap();
     match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
         Ok(_) => {}
-        Err(NOTIFIED) => return, // notified after we locked
+        Err(NOTIFIED) => {
+            thread.inner.state.store(EMPTY, SeqCst);
+            return;
+        } // should consume this notification, so prohibit spurious wakeups in next park.
         Err(_) => panic!("inconsistent park_timeout state"),
     }