1use core::error::Error;
4use core::fmt;
5
6use super::event::Event;
7use super::once_cell::{OnceCell, SetError};
8
9#[derive(Debug, PartialEq, Eq)]
12pub struct SetOnceError<T>(pub T);
13
14impl<T> fmt::Display for SetOnceError<T> {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 f.write_str("SetOnceError")
17 }
18}
19
20impl<T: fmt::Debug> Error for SetOnceError<T> {}
21
22pub struct SetOnce<T> {
39 cell: OnceCell<T>,
40 ready: Event,
41}
42
43impl<T> SetOnce<T> {
44 loom_const_fn! {
45 pub fn new() -> Self {
47 Self { cell: OnceCell::new(), ready: Event::new() }
48 }
49 }
50
51 loom_const_fn! {
52 pub fn const_new() -> Self {
54 Self::new()
55 }
56 }
57
58 pub fn new_with(value: Option<T>) -> Self {
60 match value {
61 Some(value) => Self::from(value),
62 None => Self::new(),
63 }
64 }
65
66 loom_const_fn! {
67 pub fn const_new_with(value: T) -> Self {
69 Self { cell: OnceCell::const_new_with(value), ready: Event::new_set(true) }
70 }
71 }
72
73 pub fn initialized(&self) -> bool {
75 self.cell.initialized()
76 }
77
78 pub fn get(&self) -> Option<&T> {
80 self.cell.get()
81 }
82
83 pub fn set(&self, value: T) -> Result<(), SetOnceError<T>> {
91 match self.cell.set(value) {
92 Ok(()) => {
93 self.ready.set();
94 Ok(())
95 }
96 Err(SetError::AlreadyInitializedError(value) | SetError::InitializingError(value)) => {
97 Err(SetOnceError(value))
98 }
99 }
100 }
101
102 pub fn into_inner(self) -> Option<T> {
104 self.cell.into_inner()
105 }
106
107 pub async fn wait(&self) -> &T {
112 loop {
113 if let Some(value) = self.cell.get() {
114 return value;
115 }
116 self.ready.wait().await;
117 }
118 }
119}
120
121impl<T> Default for SetOnce<T> {
122 fn default() -> Self {
123 Self::new()
124 }
125}
126
127impl<T: fmt::Debug> fmt::Debug for SetOnce<T> {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 f.debug_struct("SetOnce")
130 .field("value", &self.get())
131 .finish()
132 }
133}
134
135impl<T: Clone> Clone for SetOnce<T> {
136 fn clone(&self) -> Self {
137 Self::new_with(self.get().cloned())
138 }
139}
140
141impl<T: PartialEq> PartialEq for SetOnce<T> {
142 fn eq(&self, other: &Self) -> bool {
143 self.get() == other.get()
144 }
145}
146
147impl<T: Eq> Eq for SetOnce<T> {}
148
149impl<T> From<T> for SetOnce<T> {
150 fn from(value: T) -> Self {
151 Self::const_new_with(value)
152 }
153}
154
155#[cfg(all(test, not(loom)))]
156mod tests {
157 use super::*;
158 use crate::sync::test_support::{Polled, block_on};
159 use std::sync::Arc;
160
161 #[test]
162 fn a_set_wakes_every_waiter_and_later_waits_pass() {
163 let once = SetOnce::new();
164 let mut first = Polled::new(once.wait());
165 first.pending();
166 let mut second = Polled::new(once.wait());
167 second.pending();
168 assert!(!once.initialized());
169 assert_eq!(once.set(7), Ok(()));
170 assert!(once.initialized());
171 assert_eq!((first.wakes(), second.wakes()), (1, 1));
172 assert_eq!((first.ready(), second.ready()), (&7, &7));
173 assert_eq!(Polled::new(once.wait()).ready(), &7);
174 }
175
176 #[test]
177 fn a_second_set_gives_its_value_back() {
178 let once = SetOnce::new();
179 assert_eq!(once.set(1), Ok(()));
180 let err = once.set(2).unwrap_err();
181 assert_eq!(err, SetOnceError(2));
182 assert_eq!(err.0, 2);
183 assert_eq!(err.to_string(), "SetOnceError");
184 assert_eq!(once.get(), Some(&1));
185 assert_eq!(once.into_inner(), Some(1));
186 }
187
188 #[test]
189 fn a_dropped_wait_leaves_the_rest_to_their_wake() {
190 let once = SetOnce::new();
191 let mut kept = Polled::new(once.wait());
192 kept.pending();
193 Polled::new(once.wait()).pending();
194 assert_eq!(once.set(5), Ok(()));
195 assert_eq!(kept.ready(), &5);
196 }
197
198 #[test]
199 fn constructors_conversions_and_traits() {
200 static FULL: SetOnce<u8> = SetOnce::const_new_with(3);
201 static EMPTY: SetOnce<u8> = SetOnce::const_new();
202 assert_eq!(FULL.get(), Some(&3));
203 assert!(FULL.set(4).is_err());
204 assert_eq!(*block_on(FULL.wait()), 3);
205 assert_eq!(EMPTY.get(), None);
206 assert_eq!(SetOnce::new_with(Some(1)).get(), Some(&1));
207 assert_eq!(SetOnce::<u8>::new_with(None).get(), None);
208 assert_eq!(SetOnce::<u8>::default().into_inner(), None);
209 assert_eq!(
210 format!("{:?}", SetOnce::from(2)),
211 "SetOnce { value: Some(2) }"
212 );
213 let once = SetOnce::from(String::from("x"));
214 assert_eq!(once.clone(), once);
215 assert_ne!(once, SetOnce::new());
216 }
217
218 #[test]
219 fn a_thread_waiting_for_the_value_gets_it() {
220 let once = Arc::new(SetOnce::new());
221 let waiter = {
222 let once = Arc::clone(&once);
223 std::thread::spawn(move || *block_on(once.wait()))
224 };
225 assert_eq!(once.set(9), Ok(()));
226 assert_eq!(waiter.join().expect("waiter"), 9);
227 }
228
229 #[test]
230 fn two_sets_at_once_leave_exactly_one_winner() {
231 for _ in 0..if cfg!(miri) { 3 } else { 200 } {
232 let once = Arc::new(SetOnce::new());
233 let racers: Vec<_> = [1, 2]
234 .into_iter()
235 .map(|n| {
236 let once = Arc::clone(&once);
237 std::thread::spawn(move || once.set(n).is_ok())
238 })
239 .collect();
240 let wins = racers
241 .into_iter()
242 .map(|racer| racer.join().expect("racer"))
243 .filter(|won| *won)
244 .count();
245 assert_eq!(wins, 1);
246 assert!(once.get().is_some());
247 }
248 }
249}