@@ -800,7 +800,11 @@ pub fn park() {
800
800
match thread. inner . state . compare_exchange ( EMPTY , PARKED , SeqCst , SeqCst ) {
801
801
Ok ( _) => { }
802
802
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" ) ;
804
808
return ;
805
809
} // should consume this notification, so prohibit spurious wakeups in next park.
806
810
Err ( _) => panic ! ( "inconsistent park state" ) ,
@@ -889,7 +893,11 @@ pub fn park_timeout(dur: Duration) {
889
893
match thread. inner . state . compare_exchange ( EMPTY , PARKED , SeqCst , SeqCst ) {
890
894
Ok ( _) => { }
891
895
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" ) ;
893
901
return ;
894
902
} // should consume this notification, so prohibit spurious wakeups in next park.
895
903
Err ( _) => panic ! ( "inconsistent park_timeout state" ) ,
@@ -1058,6 +1066,8 @@ impl Thread {
1058
1066
/// [park]: fn.park.html
1059
1067
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1060
1068
pub fn unpark ( & self ) {
1069
+ // We must unconditionally write NOTIFIED here to
1070
+ // synchronize with a read in `park`.
1061
1071
match self . inner . state . swap ( NOTIFIED , SeqCst ) {
1062
1072
EMPTY => return , // no one was waiting
1063
1073
NOTIFIED => return , // already unparked
0 commit comments