Skip to content

Commit 7308115

Browse files
committed
---
yaml --- r: 29769 b: refs/heads/incoming c: 6e93d67 h: refs/heads/master i: 29767: 45a057b v: v3
1 parent 5ed5b78 commit 7308115

File tree

2 files changed

+93
-17
lines changed

2 files changed

+93
-17
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: d324a424d8f84b1eb049b12cf34182bda91b0024
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
9-
refs/heads/incoming: 7cf21e52ebd8ac2b3ce6d0aac8292bf55c39477e
9+
refs/heads/incoming: 6e93d67dbaeaef299bbcbb5cc9516d0efeb949c5
1010
refs/heads/dist-snap: 2f32a1581f522e524009138b33b1c7049ced668d
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/incoming/src/libstd/sync.rs

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -783,11 +783,11 @@ mod tests {
783783
}
784784
}
785785
#[cfg(test)]
786-
fn test_rwlock_exclusion(mode1: rwlock_mode, mode2: rwlock_mode) {
786+
fn test_rwlock_exclusion(x: ~rwlock, mode1: rwlock_mode,
787+
mode2: rwlock_mode) {
787788
// Test mutual exclusion between readers and writers. Just like the
788789
// mutex mutual exclusion test, a ways above.
789790
let (c,p) = pipes::stream();
790-
let x = ~rwlock();
791791
let x2 = ~x.clone();
792792
let sharedstate = ~0;
793793
let ptr = ptr::addr_of(*sharedstate);
@@ -815,23 +815,22 @@ mod tests {
815815
}
816816
#[test]
817817
fn test_rwlock_readers_wont_modify_the_data() {
818-
test_rwlock_exclusion(read, write);
819-
test_rwlock_exclusion(write, read);
820-
test_rwlock_exclusion(read, downgrade);
821-
test_rwlock_exclusion(downgrade, read);
818+
test_rwlock_exclusion(~rwlock(), read, write);
819+
test_rwlock_exclusion(~rwlock(), write, read);
820+
test_rwlock_exclusion(~rwlock(), read, downgrade);
821+
test_rwlock_exclusion(~rwlock(), downgrade, read);
822822
}
823823
#[test]
824824
fn test_rwlock_writers_and_writers() {
825-
test_rwlock_exclusion(write, write);
826-
test_rwlock_exclusion(write, downgrade);
827-
test_rwlock_exclusion(downgrade, write);
828-
test_rwlock_exclusion(downgrade, downgrade);
825+
test_rwlock_exclusion(~rwlock(), write, write);
826+
test_rwlock_exclusion(~rwlock(), write, downgrade);
827+
test_rwlock_exclusion(~rwlock(), downgrade, write);
828+
test_rwlock_exclusion(~rwlock(), downgrade, downgrade);
829829
}
830830
#[cfg(test)]
831-
fn test_rwlock_handshake(mode1: rwlock_mode, mode2: rwlock_mode,
832-
make_mode2_go_first: bool) {
831+
fn test_rwlock_handshake(x: ~rwlock, mode1: rwlock_mode,
832+
mode2: rwlock_mode, make_mode2_go_first: bool) {
833833
// Much like sem_multi_resource.
834-
let x = ~rwlock();
835834
let x2 = ~x.clone();
836835
let (c1,p1) = pipes::stream();
837836
let (c2,p2) = pipes::stream();
@@ -860,14 +859,29 @@ mod tests {
860859
}
861860
#[test]
862861
fn test_rwlock_readers_and_readers() {
863-
test_rwlock_handshake(read, read, false);
862+
test_rwlock_handshake(~rwlock(), read, read, false);
864863
// The downgrader needs to get in before the reader gets in, otherwise
865864
// they cannot end up reading at the same time.
866-
test_rwlock_handshake(downgrade_read, read, false);
867-
test_rwlock_handshake(read, downgrade_read, true);
865+
test_rwlock_handshake(~rwlock(), downgrade_read, read, false);
866+
test_rwlock_handshake(~rwlock(), read, downgrade_read, true);
868867
// Two downgrade_reads can never both end up reading at the same time.
869868
}
870869
#[test]
870+
fn test_rwlock_downgrade_unlock() {
871+
// Tests that downgrade can unlock the lock in both modes
872+
let x = ~rwlock();
873+
do lock_rwlock_in_mode(x, downgrade) { }
874+
test_rwlock_handshake(x, read, read, false);
875+
let y = ~rwlock();
876+
do lock_rwlock_in_mode(y, downgrade_read) { }
877+
test_rwlock_exclusion(y, write, write);
878+
}
879+
#[test]
880+
fn test_rwlock_read_recursive() {
881+
let x = ~rwlock();
882+
do x.read { do x.read { } }
883+
}
884+
#[test]
871885
fn test_rwlock_cond_wait() {
872886
// As test_mutex_cond_wait above.
873887
let x = ~rwlock();
@@ -902,6 +916,53 @@ mod tests {
902916
let _ = port.recv(); // Wait until child wakes up
903917
do x.read { } // Just for good measure
904918
}
919+
#[cfg(test)]
920+
fn test_rwlock_cond_broadcast_helper(num_waiters: uint, dg1: bool,
921+
dg2: bool) {
922+
// Much like the mutex broadcast test. Downgrade-enabled.
923+
fn lock_cond(x: &rwlock, downgrade: bool, blk: fn(c: &condvar)) {
924+
if downgrade {
925+
do x.write_downgrade |mode| { mode.write_cond(blk) }
926+
} else {
927+
x.write_cond(blk)
928+
}
929+
}
930+
let x = ~rwlock();
931+
let mut ports = ~[];
932+
933+
for num_waiters.times {
934+
let xi = ~x.clone();
935+
let (chan, port) = pipes::stream();
936+
vec::push(ports, port);
937+
do task::spawn {
938+
do lock_cond(xi, dg1) |cond| {
939+
chan.send(());
940+
cond.wait();
941+
chan.send(());
942+
}
943+
}
944+
}
945+
946+
// wait until all children get in the mutex
947+
for ports.each |port| { let _ = port.recv(); }
948+
do lock_cond(x, dg2) |cond| {
949+
let num_woken = cond.broadcast();
950+
assert num_woken == num_waiters;
951+
}
952+
// wait until all children wake up
953+
for ports.each |port| { let _ = port.recv(); }
954+
}
955+
#[test]
956+
fn test_rwlock_cond_broadcast() {
957+
test_rwlock_cond_broadcast_helper(0, true, true);
958+
test_rwlock_cond_broadcast_helper(0, true, false);
959+
test_rwlock_cond_broadcast_helper(0, false, true);
960+
test_rwlock_cond_broadcast_helper(0, false, false);
961+
test_rwlock_cond_broadcast_helper(12, true, true);
962+
test_rwlock_cond_broadcast_helper(12, true, false);
963+
test_rwlock_cond_broadcast_helper(12, false, true);
964+
test_rwlock_cond_broadcast_helper(12, false, false);
965+
}
905966
#[cfg(test)] #[ignore(cfg(windows))]
906967
fn rwlock_kill_helper(mode1: rwlock_mode, mode2: rwlock_mode) {
907968
// Mutex must get automatically unlocked if failed/killed within.
@@ -925,6 +986,21 @@ mod tests {
925986
fn test_rwlock_reader_killed_reader() { rwlock_kill_helper(read, read ); }
926987
#[test] #[ignore(cfg(windows))]
927988
fn test_rwlock_writer_killed_writer() { rwlock_kill_helper(write,write); }
989+
#[test] #[ignore(cfg(windows))]
990+
fn test_rwlock_kill_downgrader() {
991+
rwlock_kill_helper(downgrade, read);
992+
rwlock_kill_helper(read, downgrade);
993+
rwlock_kill_helper(downgrade, write);
994+
rwlock_kill_helper(write, downgrade);
995+
rwlock_kill_helper(downgrade_read, read);
996+
rwlock_kill_helper(read, downgrade_read);
997+
rwlock_kill_helper(downgrade_read, write);
998+
rwlock_kill_helper(write, downgrade_read);
999+
rwlock_kill_helper(downgrade_read, downgrade);
1000+
rwlock_kill_helper(downgrade_read, downgrade);
1001+
rwlock_kill_helper(downgrade, downgrade_read);
1002+
rwlock_kill_helper(downgrade, downgrade_read);
1003+
}
9281004
#[test] #[should_fail] #[ignore(cfg(windows))]
9291005
fn test_rwlock_downgrade_cant_swap() {
9301006
// Tests that you can't downgrade with a different rwlock's token.

0 commit comments

Comments
 (0)