Skip to content

Commit bc14d71

Browse files
committed
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.
2 parents c7cba3d + 3e1254d commit bc14d71

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

src/libstd/sync/once.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,11 @@ impl Once {
220220
#[stable(feature = "rust1", since = "1.0.0")]
221221
pub fn call_once<F>(&self, f: F) where F: FnOnce() {
222222
// Fast path, just see if we've completed initialization.
223-
if self.state.load(Ordering::SeqCst) == COMPLETE {
223+
// An `Acquire` load is enough because that makes all the initialization
224+
// operations visible to us. The cold path uses SeqCst consistently
225+
// because the performance difference really does not matter there,
226+
// and SeqCst minimizes the chances of something going wrong.
227+
if self.state.load(Ordering::Acquire) == COMPLETE {
224228
return
225229
}
226230

@@ -277,7 +281,11 @@ impl Once {
277281
#[unstable(feature = "once_poison", issue = "33577")]
278282
pub fn call_once_force<F>(&self, f: F) where F: FnOnce(&OnceState) {
279283
// same as above, just with a different parameter to `call_inner`.
280-
if self.state.load(Ordering::SeqCst) == COMPLETE {
284+
// An `Acquire` load is enough because that makes all the initialization
285+
// operations visible to us. The cold path uses SeqCst consistently
286+
// because the performance difference really does not matter there,
287+
// and SeqCst minimizes the chances of something going wrong.
288+
if self.state.load(Ordering::Acquire) == COMPLETE {
281289
return
282290
}
283291

0 commit comments

Comments
 (0)