@@ -800,7 +800,11 @@ pub fn park() {
800800 match thread. inner . state . compare_exchange ( EMPTY , PARKED , SeqCst , SeqCst ) {
801801 Ok ( _) => { }
802802 Err ( NOTIFIED ) => {
803- thread. inner . state . swap ( EMPTY , SeqCst ) ;
803+ // We must read again here, even though we know it will be NOTIFY,
804+ // to synchronize with an write in `unpark` that occurred since we
805+ // last read.
806+ let old = thread. inner . state . swap ( EMPTY , SeqCst ) ;
807+ assert_eq ! ( old, NOTIFIED , "park state changed unexpectedly" ) ;
804808 return ;
805809 } // should consume this notification, so prohibit spurious wakeups in next park.
806810 Err ( _) => panic ! ( "inconsistent park state" ) ,
@@ -889,7 +893,11 @@ pub fn park_timeout(dur: Duration) {
889893 match thread. inner . state . compare_exchange ( EMPTY , PARKED , SeqCst , SeqCst ) {
890894 Ok ( _) => { }
891895 Err ( NOTIFIED ) => {
892- thread. inner . state . swap ( EMPTY , SeqCst ) ;
896+ // We must read again here, even though we know it will be NOTIFY,
897+ // to synchronize with an write in `unpark` that occurred since we
898+ // last read.
899+ let old = thread. inner . state . swap ( EMPTY , SeqCst ) ;
900+ assert_eq ! ( old, NOTIFIED , "park state changed unexpectedly" ) ;
893901 return ;
894902 } // should consume this notification, so prohibit spurious wakeups in next park.
895903 Err ( _) => panic ! ( "inconsistent park_timeout state" ) ,
@@ -1058,6 +1066,8 @@ impl Thread {
10581066 /// [park]: fn.park.html
10591067 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10601068 pub fn unpark ( & self ) {
1069+ // We must unconditionally write NOTIFIED here to
1070+ // synchronize with a read in `park`.
10611071 match self . inner . state . swap ( NOTIFIED , SeqCst ) {
10621072 EMPTY => return , // no one was waiting
10631073 NOTIFIED => return , // already unparked
0 commit comments