@@ -78,9 +78,9 @@ use crate::thread::{self, Thread};
7878/// ```
7979#[ stable( feature = "rust1" , since = "1.0.0" ) ]
8080pub struct Once {
81- // This `state` word is actually an encoded version of just a pointer to a
82- // `Waiter` , so we add the `PhantomData` appropriately.
83- state : AtomicUsize ,
81+ // `state_and_queue` is actually an a pointer to a `Waiter` with extra state
82+ // bits , so we add the `PhantomData` appropriately.
83+ state_and_queue : AtomicUsize ,
8484 _marker : marker:: PhantomData < * mut Waiter > ,
8585}
8686
@@ -121,8 +121,8 @@ pub struct OnceState {
121121) ]
122122pub const ONCE_INIT : Once = Once :: new ( ) ;
123123
124- // Four states that a Once can be in, encoded into the lower bits of `state` in
125- // the Once structure.
124+ // Four states that a Once can be in, encoded into the lower bits of
125+ // `state_and_queue` in the Once structure.
126126const INCOMPLETE : usize = 0x0 ;
127127const POISONED : usize = 0x1 ;
128128const RUNNING : usize = 0x2 ;
@@ -151,7 +151,7 @@ impl Once {
151151 #[ stable( feature = "once_new" , since = "1.2.0" ) ]
152152 pub const fn new ( ) -> Once {
153153 Once {
154- state : AtomicUsize :: new ( INCOMPLETE ) ,
154+ state_and_queue : AtomicUsize :: new ( INCOMPLETE ) ,
155155 _marker : marker:: PhantomData ,
156156 }
157157 }
@@ -330,7 +330,7 @@ impl Once {
330330 // operations visible to us, and, this being a fast path, weaker
331331 // ordering helps with performance. This `Acquire` synchronizes with
332332 // `SeqCst` operations on the slow path.
333- self . state . load ( Ordering :: Acquire ) == COMPLETE
333+ self . state_and_queue . load ( Ordering :: Acquire ) == COMPLETE
334334 }
335335
336336 // This is a non-generic function to reduce the monomorphization cost of
@@ -352,10 +352,10 @@ impl Once {
352352 // This cold path uses SeqCst consistently because the
353353 // performance difference really does not matter there, and
354354 // SeqCst minimizes the chances of something going wrong.
355- let mut state = self . state . load ( Ordering :: SeqCst ) ;
355+ let mut state_and_queue = self . state_and_queue . load ( Ordering :: SeqCst ) ;
356356
357357 ' outer: loop {
358- match state {
358+ match state_and_queue {
359359 // If we're complete, then there's nothing to do, we just
360360 // jettison out as we shouldn't run the closure.
361361 COMPLETE => return ,
@@ -372,10 +372,11 @@ impl Once {
372372 // bits).
373373 POISONED |
374374 INCOMPLETE => {
375- let old = self . state . compare_and_swap ( state, RUNNING ,
376- Ordering :: SeqCst ) ;
377- if old != state {
378- state = old;
375+ let old = self . state_and_queue . compare_and_swap ( state_and_queue,
376+ RUNNING ,
377+ Ordering :: SeqCst ) ;
378+ if old != state_and_queue {
379+ state_and_queue = old;
379380 continue
380381 }
381382
@@ -388,7 +389,7 @@ impl Once {
388389 panicked : true ,
389390 me : self ,
390391 } ;
391- init ( state == POISONED ) ;
392+ init ( state_and_queue == POISONED ) ;
392393 complete. panicked = false ;
393394 return
394395 }
@@ -399,7 +400,7 @@ impl Once {
399400 // head of the list and bail out if we ever see a state that's
400401 // not RUNNING.
401402 _ => {
402- assert ! ( state & STATE_MASK == RUNNING ) ;
403+ assert ! ( state_and_queue & STATE_MASK == RUNNING ) ;
403404 let mut node = Waiter {
404405 thread : Some ( thread:: current ( ) ) ,
405406 signaled : AtomicBool :: new ( false ) ,
@@ -408,13 +409,13 @@ impl Once {
408409 let me = & mut node as * mut Waiter as usize ;
409410 assert ! ( me & STATE_MASK == 0 ) ;
410411
411- while state & STATE_MASK == RUNNING {
412- node. next = ( state & !STATE_MASK ) as * mut Waiter ;
413- let old = self . state . compare_and_swap ( state ,
414- me | RUNNING ,
415- Ordering :: SeqCst ) ;
416- if old != state {
417- state = old;
412+ while state_and_queue & STATE_MASK == RUNNING {
413+ node. next = ( state_and_queue & !STATE_MASK ) as * mut Waiter ;
414+ let old = self . state_and_queue . compare_and_swap ( state_and_queue ,
415+ me | RUNNING ,
416+ Ordering :: SeqCst ) ;
417+ if old != state_and_queue {
418+ state_and_queue = old;
418419 continue
419420 }
420421
@@ -424,7 +425,7 @@ impl Once {
424425 while !node. signaled . load ( Ordering :: SeqCst ) {
425426 thread:: park ( ) ;
426427 }
427- state = self . state . load ( Ordering :: SeqCst ) ;
428+ state_and_queue = self . state_and_queue . load ( Ordering :: SeqCst ) ;
428429 continue ' outer
429430 }
430431 }
@@ -444,19 +445,19 @@ impl Drop for Finish<'_> {
444445 fn drop ( & mut self ) {
445446 // Swap out our state with however we finished. We should only ever see
446447 // an old state which was RUNNING.
447- let queue = if self . panicked {
448- self . me . state . swap ( POISONED , Ordering :: SeqCst )
448+ let state_and_queue = if self . panicked {
449+ self . me . state_and_queue . swap ( POISONED , Ordering :: SeqCst )
449450 } else {
450- self . me . state . swap ( COMPLETE , Ordering :: SeqCst )
451+ self . me . state_and_queue . swap ( COMPLETE , Ordering :: SeqCst )
451452 } ;
452- assert_eq ! ( queue & STATE_MASK , RUNNING ) ;
453+ assert_eq ! ( state_and_queue & STATE_MASK , RUNNING ) ;
453454
454455 // Decode the RUNNING to a list of waiters, then walk that entire list
455456 // and wake them up. Note that it is crucial that after we store `true`
456457 // in the node it can be free'd! As a result we load the `thread` to
457458 // signal ahead of time and then unpark it after the store.
458459 unsafe {
459- let mut queue = ( queue & !STATE_MASK ) as * mut Waiter ;
460+ let mut queue = ( state_and_queue & !STATE_MASK ) as * mut Waiter ;
460461 while !queue. is_null ( ) {
461462 let next = ( * queue) . next ;
462463 let thread = ( * queue) . thread . take ( ) . unwrap ( ) ;
0 commit comments