Skip to content

Commit 778d958

Browse files
committed
Use loom Mutex, remove check in get_wait
1 parent 12e2929 commit 778d958

File tree

1 file changed

+21
-44
lines changed

1 file changed

+21
-44
lines changed

tokio/src/sync/set_once.rs

Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use super::{Notify, SetError};
2-
use crate::{loom::cell::UnsafeCell, pin};
2+
use crate::{
3+
loom::{cell::UnsafeCell, sync::Mutex},
4+
pin,
5+
};
36
use std::fmt;
47
use std::mem::MaybeUninit;
58
use std::ops::Drop;
69
use std::ptr;
710
use std::sync::atomic::{AtomicBool, Ordering};
8-
use std::sync::Mutex;
911

1012
// This file contains an implementation of an SetOnce. The value of SetOnce
1113
// can only be modified once during initialization.
@@ -181,7 +183,7 @@ impl<T> SetOnce<T> {
181183
value_set: AtomicBool::new(false),
182184
value: UnsafeCell::new(MaybeUninit::uninit()),
183185
notify: Notify::const_new(),
184-
lock: Mutex::new(()),
186+
lock: Mutex::const_new(()),
185187
}
186188
}
187189

@@ -232,7 +234,7 @@ impl<T> SetOnce<T> {
232234
value_set: AtomicBool::new(true),
233235
value: UnsafeCell::new(MaybeUninit::new(value)),
234236
notify: Notify::const_new(),
235-
lock: Mutex::new(()),
237+
lock: Mutex::const_new(()),
236238
}
237239
}
238240

@@ -271,6 +273,10 @@ impl<T> SetOnce<T> {
271273
self.value.with_mut(|ptr| (*ptr).as_mut_ptr().write(value));
272274
}
273275

276+
// Using release ordering so any threads that read a true from this
277+
// atomic is able to read the value we just stored.
278+
self.value_set.store(true, Ordering::Release);
279+
274280
// notify the waiting wakers that the value is set
275281
self.notify.notify_waiters();
276282
}
@@ -293,29 +299,13 @@ impl<T> SetOnce<T> {
293299

294300
// SAFETY: lock the mutex to ensure only one caller of set
295301
// can run at a time.
296-
match self.lock.lock() {
297-
Ok(_) => {
298-
// Using release ordering so any threads that read a true from this
299-
// atomic is able to read the value we just stored.
300-
if !self.value_set.swap(true, Ordering::Release) {
301-
// SAFETY: We are swapping the value_set AtomicBool from FALSE to
302-
// TRUE with it being previously false and followed by that we are
303-
// initializing the unsafe Cell field with the value
304-
unsafe {
305-
self.set_value(value);
306-
}
302+
let _ = self.lock.lock();
307303

308-
Ok(())
309-
} else {
310-
Err(SetError::AlreadyInitializedError(value))
311-
}
312-
}
313-
Err(_) => {
314-
// If we failed to lock the mutex, it means some other task is
315-
// trying to set the value, so we return an error.
316-
Err(SetError::InitializingError(value))
317-
}
304+
unsafe {
305+
self.set_value(value);
318306
}
307+
308+
Ok(())
319309
}
320310

321311
/// Takes the value from the cell, destroying the cell in the process.
@@ -341,41 +331,28 @@ impl<T> SetOnce<T> {
341331
/// the `SetOnce` is initialized.
342332
///
343333
/// If the `SetOnce` is already initialized, it will return the value
344-
// immediately.
334+
/// immediately.
345335
///
346336
/// # Panics
347337
///
348338
/// If the `SetOnce` is not initialized after waiting, it will panic. To
349339
/// avoid this, use `get_wait()` which returns an `Option<&T>` instead of
350340
/// `&T`.
351341
pub async fn wait(&self) -> &T {
352-
match self.get_wait().await {
353-
Some(val) => val,
354-
_ => panic!("SetOnce::wait called but the SetOnce is not initialized"),
355-
}
356-
}
357-
358-
/// Waits until set is called.
359-
///
360-
/// If the state failed to initalize it will return `None`.
361-
pub async fn get_wait(&self) -> Option<&T> {
362342
let notify_fut = self.notify.notified();
363343
pin!(notify_fut);
364344

365345
if self.value_set.load(Ordering::Acquire) {
366346
// SAFETY: the state is initialized
367-
return Some(unsafe { self.get_unchecked() });
347+
return unsafe { self.get_unchecked() };
368348
}
349+
369350
// wait until the value is set
370351
(&mut notify_fut).await;
371352

372-
// look at the state again
373-
if self.value_set.load(Ordering::Acquire) {
374-
// SAFETY: the state is initialized
375-
return Some(unsafe { self.get_unchecked() });
376-
}
377-
378-
None
353+
// SAFETY: Its not possible for the state to initialize after
354+
// waker is notified
355+
unsafe { self.get_unchecked() }
379356
}
380357
}
381358

0 commit comments

Comments
 (0)