diff options
| author | James Duley <james.duley@arm.com> | 2018-09-14 17:32:16 +0100 |
|---|---|---|
| committer | James Duley <james.duley@arm.com> | 2018-09-14 17:35:12 +0100 |
| commit | f8a78bdfdfffffe74f516eec4303d7f3d4ac879e (patch) | |
| tree | 177119e375eee491f5cea6de6cf89c7c9deec1ea /src/libstd/thread | |
| parent | 204d9608e35f7dc56e179d4539e931766fd88f28 (diff) | |
| download | rust-f8a78bdfdfffffe74f516eec4303d7f3d4ac879e.tar.gz rust-f8a78bdfdfffffe74f516eec4303d7f3d4ac879e.zip | |
Add comments and assertion to `park`/`unpark`
regarding the synchronization.
Diffstat (limited to 'src/libstd/thread')
| -rw-r--r-- | src/libstd/thread/mod.rs | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 020ea09db2a..1f03ee3e37d 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -800,7 +800,11 @@ pub fn park() { match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) { Ok(_) => {} Err(NOTIFIED) => { - thread.inner.state.swap(EMPTY, SeqCst); + // We must read again here, even though we know it will be NOTIFY, + // to synchronize with an write in `unpark` that occurred since we + // last read. + let old = thread.inner.state.swap(EMPTY, SeqCst); + assert_eq!(old, NOTIFIED, "park state changed unexpectedly"); return; } // should consume this notification, so prohibit spurious wakeups in next park. Err(_) => panic!("inconsistent park state"), @@ -889,7 +893,11 @@ pub fn park_timeout(dur: Duration) { match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) { Ok(_) => {} Err(NOTIFIED) => { - thread.inner.state.swap(EMPTY, SeqCst); + // We must read again here, even though we know it will be NOTIFY, + // to synchronize with an write in `unpark` that occurred since we + // last read. + let old = thread.inner.state.swap(EMPTY, SeqCst); + assert_eq!(old, NOTIFIED, "park state changed unexpectedly"); return; } // should consume this notification, so prohibit spurious wakeups in next park. Err(_) => panic!("inconsistent park_timeout state"), @@ -1058,6 +1066,8 @@ impl Thread { /// [park]: fn.park.html #[stable(feature = "rust1", since = "1.0.0")] pub fn unpark(&self) { + // We must unconditionally write NOTIFIED here to + // synchronize with a read in `park`. match self.inner.state.swap(NOTIFIED, SeqCst) { EMPTY => return, // no one was waiting NOTIFIED => return, // already unparked |
