@@ -763,9 +763,51 @@ mod tests {
763
763
assert result. is_err ( ) ;
764
764
// child task must have finished by the time try returns
765
765
do m. lock_cond |cond| {
766
- let _woken = cond. signal ( ) ;
767
- // FIXME(#3145) this doesn't work
768
- //assert !woken;
766
+ let woken = cond. signal ( ) ;
767
+ assert !woken;
768
+ }
769
+ }
770
+ #[ test] #[ ignore( cfg( windows) ) ]
771
+ fn test_mutex_killed_broadcast ( ) {
772
+ let m = ~mutex ( ) ;
773
+ let m2 = ~m. clone ( ) ;
774
+ let ( c, p) = pipes:: stream ( ) ;
775
+
776
+ let result: result:: result < ( ) , ( ) > = do task:: try {
777
+ let mut sibling_convos = ~[ ] ;
778
+ for 2 . times {
779
+ let ( c, p) = pipes:: stream( ) ;
780
+ let c = ~mut some( c) ;
781
+ vec:: push( sibling_convos, p) ;
782
+ let mi = ~m2. clone( ) ;
783
+ // spawn sibling task
784
+ do task:: spawn { // linked
785
+ do mi. lock_cond |cond| {
786
+ let c = option:: swap_unwrap( c) ;
787
+ c. send( ( ) ) ; // tell sibling to go ahead
788
+ let _z = send_on_failure( c) ;
789
+ cond. wait( ) ; // block forever
790
+ }
791
+ }
792
+ }
793
+ for vec:: each( sibling_convos) |p| {
794
+ let _ = p. recv( ) ; // wait for sibling to get in the mutex
795
+ }
796
+ do m2. lock { }
797
+ c. send( sibling_convos) ; // let parent wait on all children
798
+ fail;
799
+ } ;
800
+ assert result. is_err( ) ;
801
+ // child task must have finished by the time try returns
802
+ for vec:: each( p. recv( ) ) |p| { p. recv( ) ; } // wait on all its siblings
803
+ do m. lock_cond |cond| {
804
+ let woken = cond. broadcast( ) ;
805
+ assert woken == 0 ;
806
+ }
807
+ struct send_on_failure {
808
+ c : pipes:: chan < ( ) > ;
809
+ new( +c: pipes:: chan < ( ) > ) { self . c = c; }
810
+ drop { self. c. send( ( ) ) ; }
769
811
}
770
812
}
771
813
/************************************************************************
0 commit comments