]> git.lizzy.rs Git - rust.git/blob - library/std/src/lazy.rs
Auto merge of #76645 - fusion-engineering-forks:windows-lock, r=kennytm
[rust.git] / library / std / src / lazy.rs
1 //! Lazy values and one-time initialization of static data.
2
3 #[cfg(test)]
4 mod tests;
5
6 use crate::{
7     cell::{Cell, UnsafeCell},
8     fmt,
9     marker::PhantomData,
10     mem::MaybeUninit,
11     ops::{Deref, Drop},
12     panic::{RefUnwindSafe, UnwindSafe},
13     sync::Once,
14 };
15
16 #[doc(inline)]
17 #[unstable(feature = "once_cell", issue = "74465")]
18 pub use core::lazy::*;
19
20 /// A synchronization primitive which can be written to only once.
21 ///
22 /// This type is a thread-safe `OnceCell`.
23 ///
24 /// # Examples
25 ///
26 /// ```
27 /// #![feature(once_cell)]
28 ///
29 /// use std::lazy::SyncOnceCell;
30 ///
31 /// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
32 /// assert!(CELL.get().is_none());
33 ///
34 /// std::thread::spawn(|| {
35 ///     let value: &String = CELL.get_or_init(|| {
36 ///         "Hello, World!".to_string()
37 ///     });
38 ///     assert_eq!(value, "Hello, World!");
39 /// }).join().unwrap();
40 ///
41 /// let value: Option<&String> = CELL.get();
42 /// assert!(value.is_some());
43 /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
44 /// ```
45 #[unstable(feature = "once_cell", issue = "74465")]
46 pub struct SyncOnceCell<T> {
47     once: Once,
48     // Whether or not the value is initialized is tracked by `state_and_queue`.
49     value: UnsafeCell<MaybeUninit<T>>,
50     /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
51     ///
52     /// ```compile_fail,E0597
53     /// #![feature(once_cell)]
54     ///
55     /// use std::lazy::SyncOnceCell;
56     ///
57     /// struct A<'a>(&'a str);
58     ///
59     /// impl<'a> Drop for A<'a> {
60     ///     fn drop(&mut self) {}
61     /// }
62     ///
63     /// let cell = SyncOnceCell::new();
64     /// {
65     ///     let s = String::new();
66     ///     let _ = cell.set(A(&s));
67     /// }
68     /// ```
69     _marker: PhantomData<T>,
70 }
71
72 // Why do we need `T: Send`?
73 // Thread A creates a `SyncOnceCell` and shares it with
74 // scoped thread B, which fills the cell, which is
75 // then destroyed by A. That is, destructor observes
76 // a sent value.
77 #[unstable(feature = "once_cell", issue = "74465")]
78 unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
79 #[unstable(feature = "once_cell", issue = "74465")]
80 unsafe impl<T: Send> Send for SyncOnceCell<T> {}
81
82 #[unstable(feature = "once_cell", issue = "74465")]
83 impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
84 #[unstable(feature = "once_cell", issue = "74465")]
85 impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
86
87 #[unstable(feature = "once_cell", issue = "74465")]
88 impl<T> Default for SyncOnceCell<T> {
89     fn default() -> SyncOnceCell<T> {
90         SyncOnceCell::new()
91     }
92 }
93
94 #[unstable(feature = "once_cell", issue = "74465")]
95 impl<T: fmt::Debug> fmt::Debug for SyncOnceCell<T> {
96     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97         match self.get() {
98             Some(v) => f.debug_tuple("Once").field(v).finish(),
99             None => f.write_str("Once(Uninit)"),
100         }
101     }
102 }
103
104 #[unstable(feature = "once_cell", issue = "74465")]
105 impl<T: Clone> Clone for SyncOnceCell<T> {
106     fn clone(&self) -> SyncOnceCell<T> {
107         let cell = Self::new();
108         if let Some(value) = self.get() {
109             match cell.set(value.clone()) {
110                 Ok(()) => (),
111                 Err(_) => unreachable!(),
112             }
113         }
114         cell
115     }
116 }
117
118 #[unstable(feature = "once_cell", issue = "74465")]
119 impl<T> From<T> for SyncOnceCell<T> {
120     fn from(value: T) -> Self {
121         let cell = Self::new();
122         match cell.set(value) {
123             Ok(()) => cell,
124             Err(_) => unreachable!(),
125         }
126     }
127 }
128
129 #[unstable(feature = "once_cell", issue = "74465")]
130 impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
131     fn eq(&self, other: &SyncOnceCell<T>) -> bool {
132         self.get() == other.get()
133     }
134 }
135
136 #[unstable(feature = "once_cell", issue = "74465")]
137 impl<T: Eq> Eq for SyncOnceCell<T> {}
138
139 impl<T> SyncOnceCell<T> {
140     /// Creates a new empty cell.
141     #[unstable(feature = "once_cell", issue = "74465")]
142     pub const fn new() -> SyncOnceCell<T> {
143         SyncOnceCell {
144             once: Once::new(),
145             value: UnsafeCell::new(MaybeUninit::uninit()),
146             _marker: PhantomData,
147         }
148     }
149
150     /// Gets the reference to the underlying value.
151     ///
152     /// Returns `None` if the cell is empty, or being initialized. This
153     /// method never blocks.
154     #[unstable(feature = "once_cell", issue = "74465")]
155     pub fn get(&self) -> Option<&T> {
156         if self.is_initialized() {
157             // Safe b/c checked is_initialized
158             Some(unsafe { self.get_unchecked() })
159         } else {
160             None
161         }
162     }
163
164     /// Gets the mutable reference to the underlying value.
165     ///
166     /// Returns `None` if the cell is empty. This method never blocks.
167     #[unstable(feature = "once_cell", issue = "74465")]
168     pub fn get_mut(&mut self) -> Option<&mut T> {
169         if self.is_initialized() {
170             // Safe b/c checked is_initialized and we have a unique access
171             Some(unsafe { self.get_unchecked_mut() })
172         } else {
173             None
174         }
175     }
176
177     /// Sets the contents of this cell to `value`.
178     ///
179     /// Returns `Ok(())` if the cell's value was updated.
180     ///
181     /// # Examples
182     ///
183     /// ```
184     /// #![feature(once_cell)]
185     ///
186     /// use std::lazy::SyncOnceCell;
187     ///
188     /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
189     ///
190     /// fn main() {
191     ///     assert!(CELL.get().is_none());
192     ///
193     ///     std::thread::spawn(|| {
194     ///         assert_eq!(CELL.set(92), Ok(()));
195     ///     }).join().unwrap();
196     ///
197     ///     assert_eq!(CELL.set(62), Err(62));
198     ///     assert_eq!(CELL.get(), Some(&92));
199     /// }
200     /// ```
201     #[unstable(feature = "once_cell", issue = "74465")]
202     pub fn set(&self, value: T) -> Result<(), T> {
203         let mut value = Some(value);
204         self.get_or_init(|| value.take().unwrap());
205         match value {
206             None => Ok(()),
207             Some(value) => Err(value),
208         }
209     }
210
211     /// Gets the contents of the cell, initializing it with `f` if the cell
212     /// was empty.
213     ///
214     /// Many threads may call `get_or_init` concurrently with different
215     /// initializing functions, but it is guaranteed that only one function
216     /// will be executed.
217     ///
218     /// # Panics
219     ///
220     /// If `f` panics, the panic is propagated to the caller, and the cell
221     /// remains uninitialized.
222     ///
223     /// It is an error to reentrantly initialize the cell from `f`. The
224     /// exact outcome is unspecified. Current implementation deadlocks, but
225     /// this may be changed to a panic in the future.
226     ///
227     /// # Examples
228     ///
229     /// ```
230     /// #![feature(once_cell)]
231     ///
232     /// use std::lazy::SyncOnceCell;
233     ///
234     /// let cell = SyncOnceCell::new();
235     /// let value = cell.get_or_init(|| 92);
236     /// assert_eq!(value, &92);
237     /// let value = cell.get_or_init(|| unreachable!());
238     /// assert_eq!(value, &92);
239     /// ```
240     #[unstable(feature = "once_cell", issue = "74465")]
241     pub fn get_or_init<F>(&self, f: F) -> &T
242     where
243         F: FnOnce() -> T,
244     {
245         match self.get_or_try_init(|| Ok::<T, !>(f())) {
246             Ok(val) => val,
247         }
248     }
249
250     /// Gets the contents of the cell, initializing it with `f` if
251     /// the cell was empty. If the cell was empty and `f` failed, an
252     /// error is returned.
253     ///
254     /// # Panics
255     ///
256     /// If `f` panics, the panic is propagated to the caller, and
257     /// the cell remains uninitialized.
258     ///
259     /// It is an error to reentrantly initialize the cell from `f`.
260     /// The exact outcome is unspecified. Current implementation
261     /// deadlocks, but this may be changed to a panic in the future.
262     ///
263     /// # Examples
264     ///
265     /// ```
266     /// #![feature(once_cell)]
267     ///
268     /// use std::lazy::SyncOnceCell;
269     ///
270     /// let cell = SyncOnceCell::new();
271     /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
272     /// assert!(cell.get().is_none());
273     /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
274     ///     Ok(92)
275     /// });
276     /// assert_eq!(value, Ok(&92));
277     /// assert_eq!(cell.get(), Some(&92))
278     /// ```
279     #[unstable(feature = "once_cell", issue = "74465")]
280     pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
281     where
282         F: FnOnce() -> Result<T, E>,
283     {
284         // Fast path check
285         // NOTE: We need to perform an acquire on the state in this method
286         // in order to correctly synchronize `SyncLazy::force`. This is
287         // currently done by calling `self.get()`, which in turn calls
288         // `self.is_initialized()`, which in turn performs the acquire.
289         if let Some(value) = self.get() {
290             return Ok(value);
291         }
292         self.initialize(f)?;
293
294         debug_assert!(self.is_initialized());
295
296         // SAFETY: The inner value has been initialized
297         Ok(unsafe { self.get_unchecked() })
298     }
299
300     /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
301     /// `None` if the cell was empty.
302     ///
303     /// # Examples
304     ///
305     /// ```
306     /// #![feature(once_cell)]
307     ///
308     /// use std::lazy::SyncOnceCell;
309     ///
310     /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
311     /// assert_eq!(cell.into_inner(), None);
312     ///
313     /// let cell = SyncOnceCell::new();
314     /// cell.set("hello".to_string()).unwrap();
315     /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
316     /// ```
317     #[unstable(feature = "once_cell", issue = "74465")]
318     pub fn into_inner(mut self) -> Option<T> {
319         self.take()
320     }
321
322     /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
323     ///
324     /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
325     ///
326     /// Safety is guaranteed by requiring a mutable reference.
327     ///
328     /// # Examples
329     ///
330     /// ```
331     /// #![feature(once_cell)]
332     ///
333     /// use std::lazy::SyncOnceCell;
334     ///
335     /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
336     /// assert_eq!(cell.take(), None);
337     ///
338     /// let mut cell = SyncOnceCell::new();
339     /// cell.set("hello".to_string()).unwrap();
340     /// assert_eq!(cell.take(), Some("hello".to_string()));
341     /// assert_eq!(cell.get(), None);
342     /// ```
343     #[unstable(feature = "once_cell", issue = "74465")]
344     pub fn take(&mut self) -> Option<T> {
345         if self.is_initialized() {
346             self.once = Once::new();
347             // SAFETY: `self.value` is initialized and contains a valid `T`.
348             // `self.once` is reset, so `is_initialized()` will be false again
349             // which prevents the value from being read twice.
350             unsafe { Some((&mut *self.value.get()).assume_init_read()) }
351         } else {
352             None
353         }
354     }
355
356     #[inline]
357     fn is_initialized(&self) -> bool {
358         self.once.is_completed()
359     }
360
361     #[cold]
362     fn initialize<F, E>(&self, f: F) -> Result<(), E>
363     where
364         F: FnOnce() -> Result<T, E>,
365     {
366         let mut res: Result<(), E> = Ok(());
367         let slot = &self.value;
368
369         // Ignore poisoning from other threads
370         // If another thread panics, then we'll be able to run our closure
371         self.once.call_once_force(|p| {
372             match f() {
373                 Ok(value) => {
374                     unsafe { (&mut *slot.get()).write(value) };
375                 }
376                 Err(e) => {
377                     res = Err(e);
378
379                     // Treat the underlying `Once` as poisoned since we
380                     // failed to initialize our value. Calls
381                     p.poison();
382                 }
383             }
384         });
385         res
386     }
387
388     /// Safety: The value must be initialized
389     unsafe fn get_unchecked(&self) -> &T {
390         debug_assert!(self.is_initialized());
391         (&*self.value.get()).assume_init_ref()
392     }
393
394     /// Safety: The value must be initialized
395     unsafe fn get_unchecked_mut(&mut self) -> &mut T {
396         debug_assert!(self.is_initialized());
397         (&mut *self.value.get()).assume_init_mut()
398     }
399 }
400
401 unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
402     fn drop(&mut self) {
403         if self.is_initialized() {
404             // Safety: The cell is initialized and being dropped, so it can't
405             // be accessed again. We also don't touch the `T` other than
406             // dropping it, which validates our usage of #[may_dangle].
407             unsafe { (&mut *self.value.get()).assume_init_drop() };
408         }
409     }
410 }
411
412 /// A value which is initialized on the first access.
413 ///
414 /// This type is a thread-safe `Lazy`, and can be used in statics.
415 ///
416 /// # Examples
417 ///
418 /// ```
419 /// #![feature(once_cell)]
420 ///
421 /// use std::collections::HashMap;
422 ///
423 /// use std::lazy::SyncLazy;
424 ///
425 /// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
426 ///     println!("initializing");
427 ///     let mut m = HashMap::new();
428 ///     m.insert(13, "Spica".to_string());
429 ///     m.insert(74, "Hoyten".to_string());
430 ///     m
431 /// });
432 ///
433 /// fn main() {
434 ///     println!("ready");
435 ///     std::thread::spawn(|| {
436 ///         println!("{:?}", HASHMAP.get(&13));
437 ///     }).join().unwrap();
438 ///     println!("{:?}", HASHMAP.get(&74));
439 ///
440 ///     // Prints:
441 ///     //   ready
442 ///     //   initializing
443 ///     //   Some("Spica")
444 ///     //   Some("Hoyten")
445 /// }
446 /// ```
447 #[unstable(feature = "once_cell", issue = "74465")]
448 pub struct SyncLazy<T, F = fn() -> T> {
449     cell: SyncOnceCell<T>,
450     init: Cell<Option<F>>,
451 }
452
453 #[unstable(feature = "once_cell", issue = "74465")]
454 impl<T: fmt::Debug, F> fmt::Debug for SyncLazy<T, F> {
455     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456         f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
457     }
458 }
459
460 // We never create a `&F` from a `&SyncLazy<T, F>` so it is fine
461 // to not impl `Sync` for `F`
462 // we do create a `&mut Option<F>` in `force`, but this is
463 // properly synchronized, so it only happens once
464 // so it also does not contribute to this impl.
465 #[unstable(feature = "once_cell", issue = "74465")]
466 unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
467 // auto-derived `Send` impl is OK.
468
469 #[unstable(feature = "once_cell", issue = "74465")]
470 impl<T, F: UnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
471 #[unstable(feature = "once_cell", issue = "74465")]
472 impl<T, F: UnwindSafe> UnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: UnwindSafe {}
473
474 impl<T, F> SyncLazy<T, F> {
475     /// Creates a new lazy value with the given initializing
476     /// function.
477     #[unstable(feature = "once_cell", issue = "74465")]
478     pub const fn new(f: F) -> SyncLazy<T, F> {
479         SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
480     }
481 }
482
483 impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
484     /// Forces the evaluation of this lazy value and
485     /// returns a reference to result. This is equivalent
486     /// to the `Deref` impl, but is explicit.
487     ///
488     /// # Examples
489     ///
490     /// ```
491     /// #![feature(once_cell)]
492     ///
493     /// use std::lazy::SyncLazy;
494     ///
495     /// let lazy = SyncLazy::new(|| 92);
496     ///
497     /// assert_eq!(SyncLazy::force(&lazy), &92);
498     /// assert_eq!(&*lazy, &92);
499     /// ```
500     #[unstable(feature = "once_cell", issue = "74465")]
501     pub fn force(this: &SyncLazy<T, F>) -> &T {
502         this.cell.get_or_init(|| match this.init.take() {
503             Some(f) => f(),
504             None => panic!("Lazy instance has previously been poisoned"),
505         })
506     }
507 }
508
509 #[unstable(feature = "once_cell", issue = "74465")]
510 impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
511     type Target = T;
512     fn deref(&self) -> &T {
513         SyncLazy::force(self)
514     }
515 }
516
517 #[unstable(feature = "once_cell", issue = "74465")]
518 impl<T: Default> Default for SyncLazy<T> {
519     /// Creates a new lazy value using `Default` as the initializing function.
520     fn default() -> SyncLazy<T> {
521         SyncLazy::new(T::default)
522     }
523 }