about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-20 02:52:19 +0000
committerbors <bors@rust-lang.org>2018-07-20 02:52:19 +0000
commitbc14d71622378cf942a834e7c2b5358b9901f775 (patch)
treed7287a0944a97635767ce59ea6bf2e8fc40fc743 /src/libstd
parentc7cba3d33f564be140275c4fb9e33c6dc2c97b21 (diff)
parent3e1254d956d944a2909f61f733427350cd96f410 (diff)
downloadrust-bc14d71622378cf942a834e7c2b5358b9901f775.tar.gz
rust-bc14d71622378cf942a834e7c2b5358b9901f775.zip
Auto merge of #52349 - RalfJung:once, r=alexcrichton
sync::Once use release-acquire access modes

Nothing here makes a case distinction like "this happened before OR after that". All we need is to get happens-before edges whenever we see that the state/signal has been changed. Release-acquire is good enough for that.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/sync/once.rs12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 51c42995d5e..443e2a6980d 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -220,7 +220,11 @@ impl Once {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn call_once<F>(&self, f: F) where F: FnOnce() {
         // Fast path, just see if we've completed initialization.
-        if self.state.load(Ordering::SeqCst) == COMPLETE {
+        // An `Acquire` load is enough because that makes all the initialization
+        // operations visible to us. The cold path uses SeqCst consistently
+        // because the performance difference really does not matter there,
+        // and SeqCst minimizes the chances of something going wrong.
+        if self.state.load(Ordering::Acquire) == COMPLETE {
             return
         }
 
@@ -277,7 +281,11 @@ impl Once {
     #[unstable(feature = "once_poison", issue = "33577")]
     pub fn call_once_force<F>(&self, f: F) where F: FnOnce(&OnceState) {
         // same as above, just with a different parameter to `call_inner`.
-        if self.state.load(Ordering::SeqCst) == COMPLETE {
+        // An `Acquire` load is enough because that makes all the initialization
+        // operations visible to us. The cold path uses SeqCst consistently
+        // because the performance difference really does not matter there,
+        // and SeqCst minimizes the chances of something going wrong.
+        if self.state.load(Ordering::Acquire) == COMPLETE {
             return
         }