let (p, c) = comm::stream();
- do task::spawn() || {
- let arc_v : Arc<~[int]> = p.recv();
+ do task::spawn {
+ let arc_v: Arc<~[int]> = p.recv();
- let v = (*arc_v.get()).clone();
+ let v = arc_v.get().clone();
assert_eq!(v[3], 4);
};
#[test]
fn test_mutex_arc_condvar() {
unsafe {
- let arc = ~MutexArc::new(false);
- let arc2 = ~arc.clone();
- let (p,c) = comm::oneshot();
- let (c,p) = (Cell::new(c), Cell::new(p));
- do task::spawn || {
+ let arc = MutexArc::new(false);
+ let arc2 = arc.clone();
+ let (p, c) = comm::oneshot();
+ let (c, p) = (Cell::new(c), Cell::new(p));
+ do task::spawn {
// wait until parent gets in
p.take().recv();
do arc2.access_cond |state, cond| {
#[test] #[should_fail]
fn test_arc_condvar_poison() {
unsafe {
- let arc = ~MutexArc::new(1);
- let arc2 = ~arc.clone();
+ let arc = MutexArc::new(1);
+ let arc2 = arc.clone();
let (p, c) = comm::stream();
- do task::spawn_unlinked || {
+ do task::spawn_unlinked {
let _ = p.recv();
do arc2.access_cond |one, cond| {
cond.signal();
#[test] #[should_fail]
fn test_mutex_arc_poison() {
unsafe {
- let arc = ~MutexArc::new(1);
- let arc2 = ~arc.clone();
- do task::try || {
+ let arc = MutexArc::new(1);
+ let arc2 = arc.clone();
+ do task::try {
do arc2.access |one| {
assert_eq!(*one, 2);
}
#[test] #[should_fail]
pub fn test_mutex_arc_unwrap_poison() {
let arc = MutexArc::new(1);
- let arc2 = ~(&arc).clone();
+ let arc2 = arc.clone();
let (p, c) = comm::stream();
do task::spawn {
unsafe {
}
#[test] #[should_fail]
fn test_rw_arc_poison_wr() {
- let arc = ~RWArc::new(1);
- let arc2 = (*arc).clone();
- do task::try || {
+ let arc = RWArc::new(1);
+ let arc2 = arc.clone();
+ do task::try {
do arc2.write |one| {
assert_eq!(*one, 2);
}
}
#[test] #[should_fail]
fn test_rw_arc_poison_ww() {
- let arc = ~RWArc::new(1);
- let arc2 = (*arc).clone();
- do task::try || {
+ let arc = RWArc::new(1);
+ let arc2 = arc.clone();
+ do task::try {
do arc2.write |one| {
assert_eq!(*one, 2);
}
}
#[test] #[should_fail]
fn test_rw_arc_poison_dw() {
- let arc = ~RWArc::new(1);
- let arc2 = (*arc).clone();
- do task::try || {
+ let arc = RWArc::new(1);
+ let arc2 = arc.clone();
+ do task::try {
do arc2.write_downgrade |mut write_mode| {
do write_mode.write |one| {
assert_eq!(*one, 2);
}
#[test]
fn test_rw_arc_no_poison_rr() {
- let arc = ~RWArc::new(1);
- let arc2 = (*arc).clone();
- do task::try || {
+ let arc = RWArc::new(1);
+ let arc2 = arc.clone();
+ do task::try {
do arc2.read |one| {
assert_eq!(*one, 2);
}
}
#[test]
fn test_rw_arc_no_poison_rw() {
- let arc = ~RWArc::new(1);
- let arc2 = (*arc).clone();
- do task::try || {
+ let arc = RWArc::new(1);
+ let arc2 = arc.clone();
+ do task::try {
do arc2.read |one| {
assert_eq!(*one, 2);
}
}
#[test]
fn test_rw_arc_no_poison_dr() {
- let arc = ~RWArc::new(1);
- let arc2 = (*arc).clone();
- do task::try || {
+ let arc = RWArc::new(1);
+ let arc2 = arc.clone();
+ do task::try {
do arc2.write_downgrade |write_mode| {
let read_mode = arc2.downgrade(write_mode);
- do (&read_mode).read |one| {
+ do read_mode.read |one| {
assert_eq!(*one, 2);
}
}
}
#[test]
fn test_rw_arc() {
- let arc = ~RWArc::new(0);
- let arc2 = (*arc).clone();
- let (p,c) = comm::stream();
+ let arc = RWArc::new(0);
+ let arc2 = arc.clone();
+ let (p, c) = comm::stream();
- do task::spawn || {
+ do task::spawn {
do arc2.write |num| {
do 10.times {
let tmp = *num;
// Readers try to catch the writer in the act
let mut children = ~[];
do 5.times {
- let arc3 = (*arc).clone();
+ let arc3 = arc.clone();
let mut builder = task::task();
builder.future_result(|r| children.push(r));
do builder.spawn {
// (4) tells writer and all other readers to contend as it downgrades.
// (5) Writer attempts to set state back to 42, while downgraded task
// and all reader tasks assert that it's 31337.
- let arc = ~RWArc::new(0);
+ let arc = RWArc::new(0);
// Reader tasks
let mut reader_convos = ~[];
do 10.times {
- let ((rp1,rc1),(rp2,rc2)) = (comm::stream(),comm::stream());
+ let ((rp1, rc1), (rp2, rc2)) = (comm::stream(), comm::stream());
reader_convos.push((rc1, rp2));
- let arcn = (*arc).clone();
- do task::spawn || {
+ let arcn = arc.clone();
+ do task::spawn {
rp1.recv(); // wait for downgrader to give go-ahead
do arcn.read |state| {
assert_eq!(*state, 31337);
}
// Writer task
- let arc2 = (*arc).clone();
- let ((wp1,wc1),(wp2,wc2)) = (comm::stream(),comm::stream());
+ let arc2 = arc.clone();
+ let ((wp1, wc1), (wp2, wc2)) = (comm::stream(), comm::stream());
do task::spawn || {
wp1.recv();
do arc2.write_cond |state, cond| {
}
}
let read_mode = arc.downgrade(write_mode);
- do (&read_mode).read |state| {
+ do read_mode.read |state| {
// complete handshake with other readers
for &(_, ref rp) in reader_convos.iter() {
rp.recv()
// line in RWLock::write_cond() that looks like:
// "blk(&Condvar { order: opt_lock, ..*cond })"
// with just "blk(cond)".
- let x = ~RWArc::new(true);
+ let x = RWArc::new(true);
let (wp, wc) = comm::stream();
// writer task
- let xw = (*x).clone();
+ let xw = x.clone();
do task::spawn {
do xw.write_cond |state, c| {
wc.send(()); // tell downgrader it's ok to go
c.signal();
}
// make a reader task to trigger the "reader cloud lock" handoff
- let xr = (*x).clone();
+ let xr = x.clone();
let (rp, rc) = comm::stream();
do task::spawn {
rc.send(());
#[cfg(test)]
mod tests {
-
use sync::*;
use std::cast;
************************************************************************/
#[test]
fn test_sem_acquire_release() {
- let s = ~Semaphore::new(1);
+ let s = Semaphore::new(1);
s.acquire();
s.release();
s.acquire();
}
#[test]
fn test_sem_basic() {
- let s = ~Semaphore::new(1);
+ let s = Semaphore::new(1);
do s.access { }
}
#[test]
fn test_sem_as_mutex() {
- let s = ~Semaphore::new(1);
- let s2 = ~s.clone();
- do task::spawn || {
+ let s = Semaphore::new(1);
+ let s2 = s.clone();
+ do task::spawn {
do s2.access {
do 5.times { task::deschedule(); }
}
#[test]
fn test_sem_as_cvar() {
/* Child waits and parent signals */
- let (p,c) = comm::stream();
- let s = ~Semaphore::new(0);
- let s2 = ~s.clone();
- do task::spawn || {
+ let (p, c) = comm::stream();
+ let s = Semaphore::new(0);
+ let s2 = s.clone();
+ do task::spawn {
s2.acquire();
c.send(());
}
let _ = p.recv();
/* Parent waits and child signals */
- let (p,c) = comm::stream();
- let s = ~Semaphore::new(0);
- let s2 = ~s.clone();
- do task::spawn || {
+ let (p, c) = comm::stream();
+ let s = Semaphore::new(0);
+ let s2 = s.clone();
+ do task::spawn {
do 5.times { task::deschedule(); }
s2.release();
let _ = p.recv();
fn test_sem_multi_resource() {
// Parent and child both get in the critical section at the same
// time, and shake hands.
- let s = ~Semaphore::new(2);
- let s2 = ~s.clone();
+ let s = Semaphore::new(2);
+ let s2 = s.clone();
let (p1,c1) = comm::stream();
let (p2,c2) = comm::stream();
- do task::spawn || {
+ do task::spawn {
do s2.access {
let _ = p2.recv();
c1.send(());
// Force the runtime to schedule two threads on the same sched_loop.
// When one blocks, it should schedule the other one.
do task::spawn_sched(task::SingleThreaded) {
- let s = ~Semaphore::new(1);
- let s2 = ~s.clone();
- let (p,c) = comm::stream();
+ let s = Semaphore::new(1);
+ let s2 = s.clone();
+ let (p, c) = comm::stream();
let child_data = Cell::new((s2, c));
do s.access {
let (s2, c) = child_data.take();
- do task::spawn || {
+ do task::spawn {
c.send(());
do s2.access { }
c.send(());
fn test_mutex_lock() {
// Unsafely achieve shared state, and do the textbook
// "load tmp = move ptr; inc tmp; store ptr <- tmp" dance.
- let (p,c) = comm::stream();
- let m = ~Mutex::new();
+ let (p, c) = comm::stream();
+ let m = Mutex::new();
let m2 = m.clone();
let mut sharedstate = ~0;
{
let ptr: *int = &*sharedstate;
- do task::spawn || {
+ do task::spawn {
let sharedstate: &mut int =
unsafe { cast::transmute(ptr) };
- access_shared(sharedstate, m2, 10);
+ access_shared(sharedstate, &m2, 10);
c.send(());
}
}
{
- access_shared(sharedstate, m, 10);
+ access_shared(sharedstate, &m, 10);
let _ = p.recv();
assert_eq!(*sharedstate, 20);
}
#[test]
fn test_mutex_cond_wait() {
- let m = ~Mutex::new();
+ let m = Mutex::new();
// Child wakes up parent
do m.lock_cond |cond| {
- let m2 = ~m.clone();
- do task::spawn || {
+ let m2 = m.clone();
+ do task::spawn {
do m2.lock_cond |cond| {
let woken = cond.signal();
assert!(woken);
}
// Parent wakes up child
let (port,chan) = comm::stream();
- let m3 = ~m.clone();
- do task::spawn || {
+ let m3 = m.clone();
+ do task::spawn {
do m3.lock_cond |cond| {
chan.send(());
cond.wait();
}
#[cfg(test)]
fn test_mutex_cond_broadcast_helper(num_waiters: uint) {
- let m = ~Mutex::new();
+ let m = Mutex::new();
let mut ports = ~[];
do num_waiters.times {
- let mi = ~m.clone();
+ let mi = m.clone();
let (port, chan) = comm::stream();
ports.push(port);
- do task::spawn || {
+ do task::spawn {
do mi.lock_cond |cond| {
chan.send(());
cond.wait();
}
#[test]
fn test_mutex_cond_no_waiter() {
- let m = ~Mutex::new();
- let m2 = ~m.clone();
- do task::try || {
+ let m = Mutex::new();
+ let m2 = m.clone();
+ do task::try {
do m.lock_cond |_x| { }
};
do m2.lock_cond |cond| {
#[test]
fn test_mutex_killed_simple() {
// Mutex must get automatically unlocked if failed/killed within.
- let m = ~Mutex::new();
- let m2 = ~m.clone();
+ let m = Mutex::new();
+ let m2 = m.clone();
- let result: result::Result<(),()> = do task::try || {
+ let result: result::Result<(),()> = do task::try {
do m2.lock {
fail!();
}
fn test_mutex_killed_cond() {
// Getting killed during cond wait must not corrupt the mutex while
// unwinding (e.g. double unlock).
- let m = ~Mutex::new();
- let m2 = ~m.clone();
+ let m = Mutex::new();
+ let m2 = m.clone();
- let result: result::Result<(),()> = do task::try || {
- let (p,c) = comm::stream();
+ let result: result::Result<(),()> = do task::try {
+ let (p, c) = comm::stream();
do task::spawn || { // linked
let _ = p.recv(); // wait for sibling to get in the mutex
task::deschedule();
fn test_mutex_killed_broadcast() {
use std::unstable::finally::Finally;
- let m = ~Mutex::new();
- let m2 = ~m.clone();
- let (p,c) = comm::stream();
+ let m = Mutex::new();
+ let m2 = m.clone();
+ let (p, c) = comm::stream();
- let result: result::Result<(),()> = do task::try || {
+ let result: result::Result<(),()> = do task::try {
let mut sibling_convos = ~[];
do 2.times {
- let (p,c) = comm::stream();
+ let (p, c) = comm::stream();
let c = Cell::new(c);
sibling_convos.push(p);
- let mi = ~m2.clone();
+ let mi = m2.clone();
// spawn sibling task
do task::spawn { // linked
do mi.lock_cond |cond| {
#[test]
fn test_mutex_cond_signal_on_0() {
// Tests that signal_on(0) is equivalent to signal().
- let m = ~Mutex::new();
+ let m = Mutex::new();
do m.lock_cond |cond| {
- let m2 = ~m.clone();
- do task::spawn || {
+ let m2 = m.clone();
+ do task::spawn {
do m2.lock_cond |cond| {
cond.signal_on(0);
}
#[test]
fn test_mutex_different_conds() {
let result = do task::try {
- let m = ~Mutex::new_with_condvars(2);
- let m2 = ~m.clone();
- let (p,c) = comm::stream();
- do task::spawn || {
+ let m = Mutex::new_with_condvars(2);
+ let m2 = m.clone();
+ let (p, c) = comm::stream();
+ do task::spawn {
do m2.lock_cond |cond| {
c.send(());
cond.wait_on(1);
#[test]
fn test_mutex_no_condvars() {
let result = do task::try {
- let m = ~Mutex::new_with_condvars(0);
+ let m = Mutex::new_with_condvars(0);
do m.lock_cond |cond| { cond.wait(); }
};
assert!(result.is_err());
let result = do task::try {
- let m = ~Mutex::new_with_condvars(0);
+ let m = Mutex::new_with_condvars(0);
do m.lock_cond |cond| { cond.signal(); }
};
assert!(result.is_err());
let result = do task::try {
- let m = ~Mutex::new_with_condvars(0);
+ let m = Mutex::new_with_condvars(0);
do m.lock_cond |cond| { cond.broadcast(); }
};
assert!(result.is_err());
}
}
#[cfg(test)]
- fn test_rwlock_exclusion(x: ~RWLock,
+ fn test_rwlock_exclusion(x: &RWLock,
mode1: RWLockMode,
mode2: RWLockMode) {
// Test mutual exclusion between readers and writers. Just like the
// mutex mutual exclusion test, a ways above.
- let (p,c) = comm::stream();
- let x2 = (*x).clone();
+ let (p, c) = comm::stream();
+ let x2 = x.clone();
let mut sharedstate = ~0;
{
let ptr: *int = &*sharedstate;
- do task::spawn || {
+ do task::spawn {
let sharedstate: &mut int =
unsafe { cast::transmute(ptr) };
access_shared(sharedstate, &x2, mode1, 10);
}
#[test]
fn test_rwlock_readers_wont_modify_the_data() {
- test_rwlock_exclusion(~RWLock::new(), Read, Write);
- test_rwlock_exclusion(~RWLock::new(), Write, Read);
- test_rwlock_exclusion(~RWLock::new(), Read, Downgrade);
- test_rwlock_exclusion(~RWLock::new(), Downgrade, Read);
+ test_rwlock_exclusion(&RWLock::new(), Read, Write);
+ test_rwlock_exclusion(&RWLock::new(), Write, Read);
+ test_rwlock_exclusion(&RWLock::new(), Read, Downgrade);
+ test_rwlock_exclusion(&RWLock::new(), Downgrade, Read);
}
#[test]
fn test_rwlock_writers_and_writers() {
- test_rwlock_exclusion(~RWLock::new(), Write, Write);
- test_rwlock_exclusion(~RWLock::new(), Write, Downgrade);
- test_rwlock_exclusion(~RWLock::new(), Downgrade, Write);
- test_rwlock_exclusion(~RWLock::new(), Downgrade, Downgrade);
+ test_rwlock_exclusion(&RWLock::new(), Write, Write);
+ test_rwlock_exclusion(&RWLock::new(), Write, Downgrade);
+ test_rwlock_exclusion(&RWLock::new(), Downgrade, Write);
+ test_rwlock_exclusion(&RWLock::new(), Downgrade, Downgrade);
}
#[cfg(test)]
- fn test_rwlock_handshake(x: ~RWLock,
+ fn test_rwlock_handshake(x: &RWLock,
mode1: RWLockMode,
mode2: RWLockMode,
make_mode2_go_first: bool) {
// Much like sem_multi_resource.
- let x2 = (*x).clone();
- let (p1,c1) = comm::stream();
- let (p2,c2) = comm::stream();
- do task::spawn || {
+ let x2 = x.clone();
+ let (p1, c1) = comm::stream();
+ let (p2, c2) = comm::stream();
+ do task::spawn {
if !make_mode2_go_first {
let _ = p2.recv(); // parent sends to us once it locks, or ...
}
}
#[test]
fn test_rwlock_readers_and_readers() {
- test_rwlock_handshake(~RWLock::new(), Read, Read, false);
+ test_rwlock_handshake(&RWLock::new(), Read, Read, false);
// The downgrader needs to get in before the reader gets in, otherwise
// they cannot end up reading at the same time.
- test_rwlock_handshake(~RWLock::new(), DowngradeRead, Read, false);
- test_rwlock_handshake(~RWLock::new(), Read, DowngradeRead, true);
+ test_rwlock_handshake(&RWLock::new(), DowngradeRead, Read, false);
+ test_rwlock_handshake(&RWLock::new(), Read, DowngradeRead, true);
// Two downgrade_reads can never both end up reading at the same time.
}
#[test]
fn test_rwlock_downgrade_unlock() {
// Tests that downgrade can unlock the lock in both modes
- let x = ~RWLock::new();
- do lock_rwlock_in_mode(x, Downgrade) { }
- test_rwlock_handshake(x, Read, Read, false);
- let y = ~RWLock::new();
- do lock_rwlock_in_mode(y, DowngradeRead) { }
- test_rwlock_exclusion(y, Write, Write);
+ let x = RWLock::new();
+ do lock_rwlock_in_mode(&x, Downgrade) { }
+ test_rwlock_handshake(&x, Read, Read, false);
+ let y = RWLock::new();
+ do lock_rwlock_in_mode(&y, DowngradeRead) { }
+ test_rwlock_exclusion(&y, Write, Write);
}
#[test]
fn test_rwlock_read_recursive() {
- let x = ~RWLock::new();
+ let x = RWLock::new();
do x.read { do x.read { } }
}
#[test]
fn test_rwlock_cond_wait() {
// As test_mutex_cond_wait above.
- let x = ~RWLock::new();
+ let x = RWLock::new();
// Child wakes up parent
do x.write_cond |cond| {
- let x2 = (*x).clone();
- do task::spawn || {
+ let x2 = x.clone();
+ do task::spawn {
do x2.write_cond |cond| {
let woken = cond.signal();
assert!(woken);
cond.wait();
}
// Parent wakes up child
- let (port,chan) = comm::stream();
- let x3 = (*x).clone();
- do task::spawn || {
+ let (port, chan) = comm::stream();
+ let x3 = x.clone();
+ do task::spawn {
do x3.write_cond |cond| {
chan.send(());
cond.wait();
do x.write_cond |c| { blk(c) }
}
}
- let x = ~RWLock::new();
+ let x = RWLock::new();
let mut ports = ~[];
do num_waiters.times {
- let xi = (*x).clone();
+ let xi = x.clone();
let (port, chan) = comm::stream();
ports.push(port);
- do task::spawn || {
+ do task::spawn {
do lock_cond(&xi, dg1) |cond| {
chan.send(());
cond.wait();
// wait until all children get in the mutex
for port in ports.iter() { let _ = port.recv(); }
- do lock_cond(x, dg2) |cond| {
+ do lock_cond(&x, dg2) |cond| {
let num_woken = cond.broadcast();
assert_eq!(num_woken, num_waiters);
}
#[cfg(test)]
fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
// Mutex must get automatically unlocked if failed/killed within.
- let x = ~RWLock::new();
- let x2 = (*x).clone();
+ let x = RWLock::new();
+ let x2 = x.clone();
let result: result::Result<(),()> = do task::try || {
do lock_rwlock_in_mode(&x2, mode1) {
};
assert!(result.is_err());
// child task must have finished by the time try returns
- do lock_rwlock_in_mode(x, mode2) { }
+ do lock_rwlock_in_mode(&x, mode2) { }
}
#[test]
fn test_rwlock_reader_killed_writer() {
}
#[test]
fn test_rwlock_writer_killed_reader() {
- rwlock_kill_helper(Write,Read );
+ rwlock_kill_helper(Write, Read);
}
#[test]
fn test_rwlock_reader_killed_reader() {
- rwlock_kill_helper(Read, Read );
+ rwlock_kill_helper(Read, Read);
}
#[test]
fn test_rwlock_writer_killed_writer() {
- rwlock_kill_helper(Write,Write);
+ rwlock_kill_helper(Write, Write);
}
#[test]
fn test_rwlock_kill_downgrader() {
#[test] #[should_fail]
fn test_rwlock_downgrade_cant_swap() {
// Tests that you can't downgrade with a different rwlock's token.
- let x = ~RWLock::new();
- let y = ~RWLock::new();
+ let x = RWLock::new();
+ let y = RWLock::new();
do x.write_downgrade |xwrite| {
let mut xopt = Some(xwrite);
do y.write_downgrade |_ywrite| {