auto merge of #12900 : alexcrichton/rust/rewrite-sync, r=brson
* Remove clone-ability from all primitives. All shared state will now come
from the usage of the primitives being shared, not the primitives being
inherently shareable. This allows for fewer allocations for stack-allocated
primitives.
* Add `Mutex<T>` and `RWLock<T>` which are stack-allocated primitives for purely
wrapping a piece of data
* Remove `RWArc<T>` in favor of `Arc<RWLock<T>>`
* Remove `MutexArc<T>` in favor of `Arc<Mutex<T>>`
* Shuffle around where things are located
* The `arc` module now only contains `Arc`
* A new `lock` module contains `Mutex`, `RWLock`, and `Barrier`
* A new `raw` module contains the primitive implementations of `Semaphore`,
`Mutex`, and `RWLock`
* The Deref/DerefMut trait was implemented where appropriate
* `CowArc` was removed, the functionality is now part of `Arc` and is tagged
with `#[experimental]`.
* The crate now has #[deny(missing_doc)]
* `Arc` now supports weak pointers
This is not a large-scale rewrite of the functionality contained within the
`sync` crate, but rather a shuffling of who does what an a thinner hierarchy of
ownership to allow for better composability.
This commit is contained in:
commit
6bf3fca8ff
48 changed files with 1738 additions and 2045 deletions
|
|
@ -18,36 +18,28 @@
|
|||
extern crate sync;
|
||||
extern crate time;
|
||||
|
||||
use sync::Arc;
|
||||
use sync::MutexArc;
|
||||
use sync::Future;
|
||||
use sync::{Arc, Future, Mutex};
|
||||
use std::os;
|
||||
use std::uint;
|
||||
|
||||
// A poor man's pipe.
|
||||
type pipe = MutexArc<Vec<uint> >;
|
||||
type pipe = Arc<Mutex<Vec<uint>>>;
|
||||
|
||||
fn send(p: &pipe, msg: uint) {
|
||||
unsafe {
|
||||
p.access_cond(|state, cond| {
|
||||
state.push(msg);
|
||||
cond.signal();
|
||||
})
|
||||
}
|
||||
let mut arr = p.lock();
|
||||
arr.push(msg);
|
||||
arr.cond.signal();
|
||||
}
|
||||
fn recv(p: &pipe) -> uint {
|
||||
unsafe {
|
||||
p.access_cond(|state, cond| {
|
||||
while state.is_empty() {
|
||||
cond.wait();
|
||||
}
|
||||
state.pop().unwrap()
|
||||
})
|
||||
let mut arr = p.lock();
|
||||
while arr.is_empty() {
|
||||
arr.cond.wait();
|
||||
}
|
||||
arr.pop().unwrap()
|
||||
}
|
||||
|
||||
fn init() -> (pipe,pipe) {
|
||||
let m = MutexArc::new(Vec::new());
|
||||
let m = Arc::new(Mutex::new(Vec::new()));
|
||||
((&m).clone(), m)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,31 +18,29 @@
|
|||
extern crate sync;
|
||||
extern crate time;
|
||||
|
||||
use sync::RWArc;
|
||||
use sync::{RWLock, Arc};
|
||||
use sync::Future;
|
||||
use std::os;
|
||||
use std::uint;
|
||||
|
||||
// A poor man's pipe.
|
||||
type pipe = RWArc<Vec<uint> >;
|
||||
type pipe = Arc<RWLock<Vec<uint>>>;
|
||||
|
||||
fn send(p: &pipe, msg: uint) {
|
||||
p.write_cond(|state, cond| {
|
||||
state.push(msg);
|
||||
cond.signal();
|
||||
})
|
||||
let mut arr = p.write();
|
||||
arr.push(msg);
|
||||
arr.cond.signal();
|
||||
}
|
||||
fn recv(p: &pipe) -> uint {
|
||||
p.write_cond(|state, cond| {
|
||||
while state.is_empty() {
|
||||
cond.wait();
|
||||
}
|
||||
state.pop().unwrap()
|
||||
})
|
||||
let mut arr = p.write();
|
||||
while arr.is_empty() {
|
||||
arr.cond.wait();
|
||||
}
|
||||
arr.pop().unwrap()
|
||||
}
|
||||
|
||||
fn init() -> (pipe,pipe) {
|
||||
let x = RWArc::new(Vec::new());
|
||||
let x = Arc::new(RWLock::new(Vec::new()));
|
||||
((&x).clone(), x)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ use std::from_str::FromStr;
|
|||
use std::iter::count;
|
||||
use std::cmp::min;
|
||||
use std::os;
|
||||
use sync::RWArc;
|
||||
use std::slice::from_elem;
|
||||
use sync::{Arc, RWLock};
|
||||
|
||||
fn A(i: uint, j: uint) -> f64 {
|
||||
((i + j) * (i + j + 1) / 2 + i + 1) as f64
|
||||
|
|
@ -28,17 +29,16 @@ fn dot(v: &[f64], u: &[f64]) -> f64 {
|
|||
sum
|
||||
}
|
||||
|
||||
fn mult(v: RWArc<Vec<f64>>,
|
||||
out: RWArc<Vec<f64>>,
|
||||
fn mult(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>,
|
||||
f: fn(&Vec<f64>, uint) -> f64) {
|
||||
// We launch in different tasks the work to be done. To finish
|
||||
// We lanch in different tasks the work to be done. To finish
|
||||
// this fuction, we need to wait for the completion of every
|
||||
// tasks. To do that, we give to each tasks a wait_chan that we
|
||||
// drop at the end of the work. At the end of this function, we
|
||||
// wait until the channel hang up.
|
||||
let (tx, rx) = channel();
|
||||
|
||||
let len = out.read(|out| out.len());
|
||||
let len = out.read().len();
|
||||
let chunk = len / 100 + 1;
|
||||
for chk in count(0, chunk) {
|
||||
if chk >= len {break;}
|
||||
|
|
@ -47,8 +47,8 @@ fn mult(v: RWArc<Vec<f64>>,
|
|||
let out = out.clone();
|
||||
spawn(proc() {
|
||||
for i in range(chk, min(len, chk + chunk)) {
|
||||
let val = v.read(|v| f(v, i));
|
||||
out.write(|out| *out.get_mut(i) = val);
|
||||
let val = f(&*v.read(), i);
|
||||
*out.write().get_mut(i) = val;
|
||||
}
|
||||
drop(tx)
|
||||
});
|
||||
|
|
@ -67,7 +67,7 @@ fn mult_Av_impl(v: &Vec<f64> , i: uint) -> f64 {
|
|||
sum
|
||||
}
|
||||
|
||||
fn mult_Av(v: RWArc<Vec<f64> >, out: RWArc<Vec<f64> >) {
|
||||
fn mult_Av(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>) {
|
||||
mult(v, out, mult_Av_impl);
|
||||
}
|
||||
|
||||
|
|
@ -79,11 +79,12 @@ fn mult_Atv_impl(v: &Vec<f64> , i: uint) -> f64 {
|
|||
sum
|
||||
}
|
||||
|
||||
fn mult_Atv(v: RWArc<Vec<f64> >, out: RWArc<Vec<f64> >) {
|
||||
fn mult_Atv(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>) {
|
||||
mult(v, out, mult_Atv_impl);
|
||||
}
|
||||
|
||||
fn mult_AtAv(v: RWArc<Vec<f64> >, out: RWArc<Vec<f64> >, tmp: RWArc<Vec<f64> >) {
|
||||
fn mult_AtAv(v: Arc<RWLock<Vec<f64>>>, out: Arc<RWLock<Vec<f64>>>,
|
||||
tmp: Arc<RWLock<Vec<f64>>>) {
|
||||
mult_Av(v, tmp.clone());
|
||||
mult_Atv(tmp, out);
|
||||
}
|
||||
|
|
@ -97,16 +98,16 @@ fn main() {
|
|||
} else {
|
||||
FromStr::from_str(args[1]).unwrap()
|
||||
};
|
||||
let u = RWArc::new(Vec::from_elem(n, 1.));
|
||||
let v = RWArc::new(Vec::from_elem(n, 1.));
|
||||
let tmp = RWArc::new(Vec::from_elem(n, 1.));
|
||||
let u = Arc::new(RWLock::new(Vec::from_elem(n, 1.)));
|
||||
let v = Arc::new(RWLock::new(Vec::from_elem(n, 1.)));
|
||||
let tmp = Arc::new(RWLock::new(Vec::from_elem(n, 1.)));
|
||||
for _ in range(0, 10) {
|
||||
mult_AtAv(u.clone(), v.clone(), tmp.clone());
|
||||
mult_AtAv(v.clone(), u.clone(), tmp.clone());
|
||||
}
|
||||
|
||||
u.read(|u| v.read(|v| {
|
||||
println!("{:.9f}",
|
||||
(dot(u.as_slice(), v.as_slice()) / dot(v.as_slice(), v.as_slice())).sqrt());
|
||||
}))
|
||||
let u = u.read();
|
||||
let v = v.read();
|
||||
println!("{:.9f}", (dot(u.as_slice(), v.as_slice()) /
|
||||
dot(v.as_slice(), v.as_slice())).sqrt());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate sync;
|
||||
use sync::RWArc;
|
||||
|
||||
fn main() {
|
||||
let arc1 = RWArc::new(true);
|
||||
let _arc2 = RWArc::new(arc1); //~ ERROR instantiating a type parameter with an incompatible type
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: lifetime of return value does not outlive the function call
|
||||
extern crate sync;
|
||||
use sync::RWArc;
|
||||
fn main() {
|
||||
let x = ~RWArc::new(1);
|
||||
let mut y = None;
|
||||
x.write_cond(|_one, cond| y = Some(cond));
|
||||
y.unwrap().wait();
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate sync;
|
||||
use sync::RWArc;
|
||||
fn main() {
|
||||
let x = ~RWArc::new(1);
|
||||
let mut y = None;
|
||||
x.write_downgrade(|write_mode| {
|
||||
y = Some(x.downgrade(write_mode));
|
||||
//~^ ERROR cannot infer
|
||||
});
|
||||
y.unwrap();
|
||||
// Adding this line causes a method unification failure instead
|
||||
// (&option::unwrap(y)).read(|state| { assert!(*state == 1); })
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate sync;
|
||||
use sync::RWArc;
|
||||
fn main() {
|
||||
let x = ~RWArc::new(1);
|
||||
let mut y = None; //~ ERROR lifetime of variable does not enclose its declaration
|
||||
x.write(|one| y = Some(one));
|
||||
*y.unwrap() = 2;
|
||||
//~^ ERROR lifetime of return value does not outlive the function call
|
||||
//~^^ ERROR dereference of reference outside its lifetime
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: lifetime of variable does not enclose its declaration
|
||||
extern crate sync;
|
||||
use sync::RWArc;
|
||||
fn main() {
|
||||
let x = ~RWArc::new(1);
|
||||
let mut y = None;
|
||||
x.write_downgrade(|write_mode| {
|
||||
(&write_mode).write_cond(|_one, cond| {
|
||||
y = Some(cond);
|
||||
})
|
||||
});
|
||||
y.unwrap().wait();
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: lifetime of variable does not enclose its declaration
|
||||
extern crate sync;
|
||||
use sync::RWArc;
|
||||
fn main() {
|
||||
let x = ~RWArc::new(1);
|
||||
let mut y = None;
|
||||
x.write_downgrade(|write_mode| y = Some(write_mode));
|
||||
y.unwrap();
|
||||
// Adding this line causes a method unification failure instead
|
||||
// (&option::unwrap(y)).write(|state| { assert!(*state == 1); })
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ use sync::Arc;
|
|||
struct A { y: Arc<int>, x: Arc<int> }
|
||||
|
||||
impl Drop for A {
|
||||
fn drop(&mut self) { println!("x={:?}", self.x.get()); }
|
||||
fn drop(&mut self) { println!("x={}", *self.x); }
|
||||
}
|
||||
fn main() {
|
||||
let a = A { y: Arc::new(1), x: Arc::new(2) };
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@ fn main() {
|
|||
let arc_v = Arc::new(v);
|
||||
|
||||
task::spawn(proc() {
|
||||
let v = arc_v.get();
|
||||
assert_eq!(*v.get(3), 4);
|
||||
assert_eq!(*arc_v.get(3), 4);
|
||||
});
|
||||
|
||||
assert_eq!(*(arc_v.get()).get(2), 3);
|
||||
assert_eq!(*arc_v.get(2), 3);
|
||||
|
||||
println!("{:?}", arc_v);
|
||||
println!("{}", *arc_v);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,10 @@ fn main() {
|
|||
let arc_v = Arc::new(v);
|
||||
|
||||
task::spawn(proc() {
|
||||
let v = arc_v.get();
|
||||
assert_eq!(*v.get(3), 4);
|
||||
assert_eq!(*arc_v.get(3), 4);
|
||||
});
|
||||
|
||||
assert_eq!(*(arc_v.get()).get(2), 3); //~ ERROR use of moved value: `arc_v`
|
||||
assert_eq!(*arc_v.get(2), 3); //~ ERROR use of moved value: `arc_v`
|
||||
|
||||
println!("{:?}", arc_v); //~ ERROR use of moved value: `arc_v`
|
||||
println!("{}", *arc_v); //~ ERROR use of moved value: `arc_v`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fn foo(blk: proc()) {
|
|||
fn main() {
|
||||
let x = Arc::new(true);
|
||||
foo(proc() {
|
||||
assert!(*x.get());
|
||||
assert!(*x);
|
||||
drop(x);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fn foo(blk: once ||) {
|
|||
fn main() {
|
||||
let x = Arc::new(true);
|
||||
foo(|| {
|
||||
assert!(*x.get());
|
||||
assert!(*x);
|
||||
drop(x);
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ fn foo(blk: ||) {
|
|||
fn main() {
|
||||
let x = Arc::new(true);
|
||||
foo(|| {
|
||||
assert!(*x.get());
|
||||
assert!(*x);
|
||||
drop(x); //~ ERROR cannot move out of captured outer variable
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: lifetime of variable does not enclose its declaration
|
||||
extern crate sync;
|
||||
use sync::Mutex;
|
||||
|
||||
fn main() {
|
||||
let m = ~sync::Mutex::new();
|
||||
let mut cond = None;
|
||||
m.lock_cond(|c| {
|
||||
cond = Some(c);
|
||||
});
|
||||
cond.unwrap().signal();
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: lifetime of method receiver does not outlive the method call
|
||||
extern crate sync;
|
||||
use sync::RWLock;
|
||||
fn main() {
|
||||
let x = ~RWLock::new();
|
||||
let mut y = None;
|
||||
x.write_cond(|cond| {
|
||||
y = Some(cond);
|
||||
});
|
||||
y.unwrap().wait();
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: cannot infer
|
||||
extern crate sync;
|
||||
use sync::RWLock;
|
||||
fn main() {
|
||||
let x = ~RWLock::new();
|
||||
let mut y = None;
|
||||
x.write_downgrade(|write_mode| {
|
||||
y = Some(x.downgrade(write_mode));
|
||||
})
|
||||
// Adding this line causes a method unification failure instead
|
||||
// (&option::unwrap(y)).read(proc() { });
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: lifetime of variable does not enclose its declaration
|
||||
extern crate sync;
|
||||
use sync::RWLock;
|
||||
fn main() {
|
||||
let x = ~RWLock::new();
|
||||
let mut y = None;
|
||||
x.write_downgrade(|write_mode| {
|
||||
(&write_mode).write_cond(|cond| {
|
||||
y = Some(cond);
|
||||
})
|
||||
});
|
||||
y.unwrap().wait();
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: lifetime of variable does not enclose its declaration
|
||||
extern crate sync;
|
||||
use sync::RWLock;
|
||||
fn main() {
|
||||
let x = ~RWLock::new();
|
||||
let mut y = None;
|
||||
x.write_downgrade(|write_mode| {
|
||||
y = Some(write_mode);
|
||||
});
|
||||
// Adding this line causes a method unification failure instead
|
||||
// (&option::unwrap(y)).write(proc() { })
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ fn foo(blk: proc()) {
|
|||
pub fn main() {
|
||||
let x = Arc::new(true);
|
||||
foo(proc() {
|
||||
assert!(*x.get());
|
||||
assert!(*x);
|
||||
drop(x);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fn foo(blk: once ||) {
|
|||
pub fn main() {
|
||||
let x = Arc::new(true);
|
||||
foo(|| {
|
||||
assert!(*x.get());
|
||||
assert!(*x);
|
||||
drop(x);
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,20 +85,20 @@ pub fn main() {
|
|||
|
||||
fn check_legs(arc: Arc<Vec<~Pet:Share+Send>>) {
|
||||
let mut legs = 0;
|
||||
for pet in arc.get().iter() {
|
||||
for pet in arc.iter() {
|
||||
legs += pet.num_legs();
|
||||
}
|
||||
assert!(legs == 12);
|
||||
}
|
||||
fn check_names(arc: Arc<Vec<~Pet:Share+Send>>) {
|
||||
for pet in arc.get().iter() {
|
||||
for pet in arc.iter() {
|
||||
pet.name(|name| {
|
||||
assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8);
|
||||
})
|
||||
}
|
||||
}
|
||||
fn check_pedigree(arc: Arc<Vec<~Pet:Share+Send>>) {
|
||||
for pet in arc.get().iter() {
|
||||
for pet in arc.iter() {
|
||||
assert!(pet.of_good_pedigree());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue