@@ -106,11 +106,14 @@ impl<T: Eq> Eq for SetOnce<T> {}
106
106
impl < T > Drop for SetOnce < T > {
107
107
fn drop ( & mut self ) {
108
108
if self . initialized ( ) {
109
+ // SAFETY: We're inside the drop implementation of SetOnce
110
+ // AND we're also initalized. This is the best way to ensure
111
+ // out data gets dropped
109
112
unsafe {
110
113
let _ = self . value . with_mut ( |ptr| ptr:: read ( ptr) . assume_init ( ) ) ;
111
114
}
112
-
113
- * self . value_set . get_mut ( ) = false ;
115
+ // no need to set the flag to false as this set once is being
116
+ // dropped
114
117
}
115
118
}
116
119
}
@@ -230,8 +233,8 @@ impl<T> SetOnce<T> {
230
233
/// Returns `true` if the `SetOnce` currently contains a value, and `false`
231
234
/// otherwise.
232
235
pub fn initialized ( & self ) -> bool {
233
- // Using acquire ordering so any threads that read a true from this
234
- // atomic is able to read the value.
236
+ // Using acquire ordering so we're able to read/catch any writes that
237
+ // are done with `Ordering::Release`
235
238
self . value_set . load ( Ordering :: Acquire )
236
239
}
237
240
@@ -299,25 +302,19 @@ impl<T> SetOnce<T> {
299
302
/// Returns `None` if the cell is empty.
300
303
pub fn into_inner ( mut self ) -> Option < T > {
301
304
if self . initialized ( ) {
302
- // SAFETY: The SetOnce is initialized, we can assume the value is
303
- // initialized and return that, when we return the value we give the
304
- // drop handler to someone else and drop is called automatically
305
- //
306
- // We set the value_set as value as we just took the value out
307
- // and the drop implementation will do nothing.
305
+ // Since we have taken ownership of self, its drop implementation
306
+ // will be called by the end of this function, to prevent a double
307
+ // free we will set the value_set to false so that the drop
308
+ // implementation does not try to drop the value again.
308
309
* self . value_set . get_mut ( ) = false ;
310
+
311
+ // SAFETY: The SetOnce is currently initialized, we can assume the
312
+ // value is initialized and return that, when we return the value
313
+ // we give the drop handler to the return scope.
309
314
Some ( unsafe { self . value . with_mut ( |ptr| ptr:: read ( ptr) . assume_init ( ) ) } )
310
315
} else {
311
316
None
312
317
}
313
- // the drop of self is called here again but it doesn't do anything since
314
- // if we dont return early then value is not initialized.
315
- }
316
-
317
- /// Takes ownership of the current value, leaving the cell empty. Returns
318
- /// `None` if the cell is empty.
319
- pub fn take ( & mut self ) -> Option < T > {
320
- std:: mem:: take ( self ) . into_inner ( )
321
318
}
322
319
323
320
/// Waits until the `SetOnce` has been initialized. Once the `SetOnce` is
0 commit comments