move concurrent stuff from libextra to libsync

This commit is contained in:
JeremyLetang 2014-01-30 15:04:47 -05:00
parent ed885e35fe
commit dd21a51d29
48 changed files with 224 additions and 145 deletions

View File

@ -49,25 +49,26 @@
# automatically generated for all stage/host/target combinations.
################################################################################
TARGET_CRATES := std extra green rustuv native flate arena glob term semver uuid
TARGET_CRATES := std extra green rustuv native flate arena glob term semver uuid sync
HOST_CRATES := syntax rustc rustdoc
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc
DEPS_std := native:rustrt
DEPS_extra := std term
DEPS_extra := std term sync
DEPS_green := std
DEPS_rustuv := std native:uv native:uv_support
DEPS_native := std
DEPS_syntax := std extra term
DEPS_rustc := syntax native:rustllvm flate arena
DEPS_rustdoc := rustc native:sundown
DEPS_rustc := syntax native:rustllvm flate arena sync
DEPS_rustdoc := rustc native:sundown sync
DEPS_flate := std native:miniz
DEPS_arena := std extra
DEPS_glob := std
DEPS_term := std
DEPS_semver := std
DEPS_uuid := std extra
DEPS_sync := std
TOOL_DEPS_compiletest := extra green rustuv
TOOL_DEPS_rustdoc := rustdoc green rustuv

View File

@ -39,7 +39,7 @@ data through the global _exchange heap_.
While Rust's type system provides the building blocks needed for safe
and efficient tasks, all of the task functionality itself is implemented
in the standard and extra libraries, which are still under development
in the standard and sync libraries, which are still under development
and do not always present a consistent or complete interface.
For your reference, these are the standard modules involved in Rust
@ -47,18 +47,43 @@ concurrency at this writing:
* [`std::task`] - All code relating to tasks and task scheduling,
* [`std::comm`] - The message passing interface,
* [`extra::comm`] - Additional messaging types based on `std::comm`,
* [`extra::sync`] - More exotic synchronization tools, including locks,
* [`extra::arc`] - The Arc (atomically reference counted) type,
for safely sharing immutable data,
* [`extra::future`] - A type representing values that may be computed concurrently and retrieved at a later time.
* [`sync::DuplexStream`] - An extension of `pipes::stream` that allows both sending and receiving,
* [`sync::SyncChan`] - An extension of `pipes::stream` that provides synchronous message sending,
* [`sync::SyncPort`] - An extension of `pipes::stream` that acknowledges each message received,
* [`sync::rendezvous`] - Creates a stream whose channel, upon sending a message, blocks until the
message is received.
* [`sync::Arc`] - The Arc (atomically reference counted) type, for safely sharing immutable data,
* [`sync::RWArc`] - A dual-mode Arc protected by a reader-writer lock,
* [`sync::MutexArc`] - An Arc with mutable data protected by a blocking mutex,
* [`sync::Semaphore`] - A counting, blocking, bounded-waiting semaphore,
* [`sync::Mutex`] - A blocking, bounded-waiting, mutual exclusion lock with an associated
FIFO condition variable,
* [`sync::RWLock`] - A blocking, no-starvation, reader-writer lock with an associated condvar,
* [`sync::Barrier`] - A barrier enables multiple tasks to synchronize the beginning
of some computation,
* [`sync::TaskPool`] - A task pool abstraction,
* [`sync::Future`] - A type encapsulating the result of a computation which may not be complete,
* [`sync::one`] - A "once initialization" primitive
* [`sync::mutex`] - A proper mutex implementation regardless of the "flavor of task" which is
acquiring the lock.
[`std::task`]: std/task/index.html
[`std::comm`]: std/comm/index.html
[`extra::comm`]: extra/comm/index.html
[`extra::sync`]: extra/sync/index.html
[`extra::arc`]: extra/arc/index.html
[`extra::future`]: extra/future/index.html
[`sync::DuplexStream`]: sync/struct.DuplexStream.html
[`sync::SyncChan`]: sync/struct.SyncChan.html
[`sync::SyncPort`]: sync/struct.SyncPort.html
[`sync::rendezvous`]: sync/fn.rendezvous.html
[`sync::Arc`]: sync/struct.Arc.html
[`sync::RWArc`]: sync/struct.RWArc.html
[`sync::MutexArc`]: sync/struct.MutexArc.html
[`sync::Semaphore`]: sync/struct.Semaphore.html
[`sync::Mutex`]: sync/struct.Mutex.html
[`sync::RWLock`]: sync/struct.RWLock.html
[`sync::Barrier`]: sync/struct.Barrier.html
[`sync::TaskPool`]: sync/struct.TaskPool.html
[`sync::Future`]: sync/struct.Future.html
[`sync::one`]: sync/one/index.html
[`sync::mutex`]: sync/mutex/index.html
# Basics
@ -254,21 +279,25 @@ let result = ports.iter().fold(0, |accum, port| accum + port.recv() );
~~~
## Backgrounding computations: Futures
With `extra::future`, rust has a mechanism for requesting a computation and getting the result
With `sync::Future`, rust has a mechanism for requesting a computation and getting the result
later.
The basic example below illustrates this.
~~~
# extern mod sync;
# fn main() {
# fn make_a_sandwich() {};
fn fib(n: u64) -> u64 {
// lengthy computation returning an uint
12586269025
}
let mut delayed_fib = extra::future::Future::spawn(proc() fib(50));
let mut delayed_fib = sync::Future::spawn(proc() fib(50));
make_a_sandwich();
println!("fib(50) = {:?}", delayed_fib.get())
# }
~~~
The call to `future::spawn` returns immediately a `future` object regardless of how long it
@ -281,6 +310,7 @@ Here is another example showing how futures allow you to background computations
be distributed on the available cores.
~~~
# extern mod sync;
# use std::vec;
fn partial_sum(start: uint) -> f64 {
let mut local_sum = 0f64;
@ -291,7 +321,7 @@ fn partial_sum(start: uint) -> f64 {
}
fn main() {
let mut futures = vec::from_fn(1000, |ind| extra::future::Future::spawn( proc() { partial_sum(ind) }));
let mut futures = vec::from_fn(1000, |ind| sync::Future::spawn( proc() { partial_sum(ind) }));
let mut final_res = 0f64;
for ft in futures.mut_iter() {
@ -309,16 +339,17 @@ add up to a significant amount of wasted memory and would require copying the sa
necessary.
To tackle this issue, one can use an Atomically Reference Counted wrapper (`Arc`) as implemented in
the `extra` library of Rust. With an Arc, the data will no longer be copied for each task. The Arc
the `sync` library of Rust. With an Arc, the data will no longer be copied for each task. The Arc
acts as a reference to the shared data and only this reference is shared and cloned.
Here is a small example showing how to use Arcs. We wish to run concurrently several computations on
a single large vector of floats. Each task needs the full vector to perform its duty.
~~~
# extern mod sync;
# use std::vec;
# use std::rand;
use extra::arc::Arc;
use sync::Arc;
fn pnorm(nums: &~[f64], p: uint) -> f64 {
nums.iter().fold(0.0, |a,b| a+(*b).powf(&(p as f64)) ).powf(&(1.0 / (p as f64)))
@ -348,23 +379,29 @@ at the power given as argument and takes the inverse power of this value). The A
created by the line
~~~
# use extra::arc::Arc;
# extern mod sync;
# use sync::Arc;
# use std::vec;
# use std::rand;
# fn main() {
# let numbers = vec::from_fn(1000000, |_| rand::random::<f64>());
let numbers_arc=Arc::new(numbers);
# }
~~~
and a clone of it is sent to each task
~~~
# use extra::arc::Arc;
# extern mod sync;
# use sync::Arc;
# use std::vec;
# use std::rand;
# fn main() {
# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
# let numbers_arc = Arc::new(numbers);
# let (port, chan) = Chan::new();
chan.send(numbers_arc.clone());
# }
~~~
copying only the wrapper and not its contents.
@ -372,15 +409,18 @@ copying only the wrapper and not its contents.
Each task recovers the underlying data by
~~~
# use extra::arc::Arc;
# extern mod sync;
# use sync::Arc;
# use std::vec;
# use std::rand;
# fn main() {
# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
# let numbers_arc=Arc::new(numbers);
# let (port, chan) = Chan::new();
# chan.send(numbers_arc.clone());
# let local_arc : Arc<~[f64]> = port.recv();
let task_numbers = local_arc.get();
# }
~~~
and can use it as if it were local.
@ -450,7 +490,7 @@ proceed).
A very common thing to do is to spawn a child task where the parent
and child both need to exchange messages with each other. The
function `extra::comm::DuplexStream()` supports this pattern. We'll
function `sync::comm::DuplexStream()` supports this pattern. We'll
look briefly at how to use it.
To see how `DuplexStream()` works, we will create a child task
@ -458,17 +498,19 @@ that repeatedly receives a `uint` message, converts it to a string, and sends
the string in response. The child terminates when it receives `0`.
Here is the function that implements the child task:
~~~{.ignore .linked-failure}
# use extra::comm::DuplexStream;
# use std::uint;
fn stringifier(channel: &DuplexStream<~str, uint>) {
let mut value: uint;
loop {
value = channel.recv();
channel.send(uint::to_str(value));
if value == 0 { break; }
~~~
# extern mod sync;
# fn main() {
# use sync::DuplexStream;
fn stringifier(channel: &DuplexStream<~str, uint>) {
let mut value: uint;
loop {
value = channel.recv();
channel.send(value.to_str());
if value == 0 { break; }
}
}
}
# }
~~~~
The implementation of `DuplexStream` supports both sending and
@ -481,15 +523,15 @@ response itself is simply the stringified version of the received value,
Here is the code for the parent task:
~~~{.ignore .linked-failure}
~~~
# extern mod sync;
# use std::task::spawn;
# use std::uint;
# use extra::comm::DuplexStream;
# use sync::DuplexStream;
# fn stringifier(channel: &DuplexStream<~str, uint>) {
# let mut value: uint;
# loop {
# value = channel.recv();
# channel.send(uint::to_str(value));
# channel.send(value.to_str());
# if value == 0u { break; }
# }
# }

View File

@ -43,6 +43,7 @@ li {list-style-type: none; }
* [The `semver` version collation library](semver/index.html)
* [The `term` terminal-handling library](term/index.html)
* [The UUID library](uuid/index.html)
* [The `sync` library for concurrency-enabled mechanisms and primitives](sync/index.html)
# Tooling

View File

@ -41,7 +41,7 @@ exceptions = [
"libstd/sync/mpsc_queue.rs", # BSD
"libstd/sync/spsc_queue.rs", # BSD
"libstd/sync/mpmc_bounded_queue.rs", # BSD
"libextra/sync/mpsc_intrusive.rs", # BSD
"libsync/sync/mpsc_intrusive.rs", # BSD
]
def check_license(name, contents):

View File

@ -34,18 +34,17 @@ Rust extras are part of the standard Rust distribution.
#[deny(non_camel_case_types)];
#[deny(missing_doc)];
extern mod sync;
#[cfg(stage0)]
macro_rules! if_ok (
($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
)
// Utility modules
pub mod c_vec;
// Concurrency
pub mod sync;
pub mod arc;
pub mod comm;
pub mod future;
pub mod task_pool;
// Collections
pub mod container;

View File

@ -13,7 +13,7 @@
use json;
use json::ToJson;
use serialize::{Encoder, Encodable, Decoder, Decodable};
use arc::{Arc,RWArc};
use sync::{Arc,RWArc};
use treemap::TreeMap;
use std::str;
use std::io;

View File

@ -331,7 +331,7 @@ pub mod write {
}
unsafe fn configure_llvm(sess: Session) {
use extra::sync::one::{Once, ONCE_INIT};
use sync::one::{Once, ONCE_INIT};
static mut INIT: Once = ONCE_INIT;
// Copy what clang does by turning on loop vectorization at O2 and

View File

@ -35,6 +35,7 @@ extern mod extra;
extern mod flate;
extern mod arena;
extern mod syntax;
extern mod sync;
use back::link;
use driver::session;

View File

@ -2660,7 +2660,7 @@ pub fn trans_crate(sess: session::Session,
output: &Path) -> CrateTranslation {
// Before we touch LLVM, make sure that multithreading is enabled.
unsafe {
use extra::sync::one::{Once, ONCE_INIT};
use sync::one::{Once, ONCE_INIT};
static mut INIT: Once = ONCE_INIT;
static mut POISONED: bool = false;
INIT.doit(|| {

View File

@ -41,7 +41,7 @@ use std::io::{fs, File, BufferedWriter};
use std::str;
use std::vec;
use extra::arc::Arc;
use sync::Arc;
use extra::json::ToJson;
use syntax::ast;
use syntax::attr;

View File

@ -18,6 +18,7 @@
extern mod syntax;
extern mod rustc;
extern mod extra;
extern mod sync;
use std::local_data;
use std::io;

View File

@ -18,7 +18,7 @@
* With simple pipes, without Arc, a copy would have to be made for each task.
*
* ```rust
* use extra::arc::Arc;
* use sync::Arc;
* use std::{rand, vec};
*
* let numbers = vec::from_fn(100, |i| (i as f32) * rand::random());
@ -38,7 +38,7 @@
* ```
*/
#[allow(missing_doc)];
#[allow(missing_doc, dead_code)];
use sync;
@ -424,7 +424,7 @@ impl<T:Freeze + Send> RWArc<T> {
* # Example
*
* ```rust
* use extra::arc::RWArc;
* use sync::RWArc;
*
* let arc = RWArc::new(1);
* arc.write_downgrade(|mut write_token| {
@ -605,7 +605,7 @@ impl<T:Clone+Send+Freeze> Clone for CowArc<T> {
#[cfg(test)]
mod tests {
use arc::*;
use super::{Arc, RWArc, MutexArc, CowArc};
use std::task;

View File

@ -15,7 +15,7 @@
* # Example
*
* ```rust
* use extra::future::Future;
* use sync::Future;
* # fn fib(n: uint) -> uint {42};
* # fn make_a_sandwich() {};
* let mut delayed_fib = Future::spawn(proc() { fib(5000) });

31
src/libsync/lib.rs Normal file
View File

@ -0,0 +1,31 @@
// Copyright 2012-2013 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.
/*!
* Concurrency-enabled mechanisms and primitives.
*/
#[crate_id = "sync#0.10-pre"];
#[crate_type = "rlib"];
#[crate_type = "dylib"];
#[license = "MIT/ASL2"];
pub use arc::{Arc, MutexArc, RWArc, RWWriteMode, RWReadMode, Condvar};
pub use sync::{Mutex, RWLock, Condvar, Semaphore, RWLockWriteMode,
RWLockReadMode, Barrier, one, mutex};
pub use comm::{DuplexStream, SyncChan, SyncPort, rendezvous};
pub use task_pool::TaskPool;
pub use future::Future;
mod arc;
mod sync;
mod comm;
mod task_pool;
mod future;

View File

@ -588,7 +588,7 @@ impl RWLock {
* # Example
*
* ```rust
* use extra::sync::RWLock;
* use sync::RWLock;
*
* let lock = RWLock::new();
* lock.write_downgrade(|mut write_token| {
@ -695,7 +695,7 @@ impl<'a> RWLockReadMode<'a> {
/// of some computation.
///
/// ```rust
/// use extra::sync::Barrier;
/// use sync::Barrier;
///
/// let barrier = Barrier::new(10);
/// for _ in range(0, 10) {
@ -759,7 +759,7 @@ impl Barrier {
#[cfg(test)]
mod tests {
use sync::*;
use sync::{Semaphore, Mutex, RWLock, Barrier, Condvar};
use std::cast;
use std::result;

View File

@ -83,7 +83,7 @@ pub static NATIVE_BLOCKED: uint = 1 << 2;
/// # Example
///
/// ```rust
/// use extra::sync::mutex::Mutex;
/// use sync::mutex::Mutex;
///
/// let mut m = Mutex::new();
/// let guard = m.lock();
@ -113,7 +113,7 @@ enum Flavor {
/// # Example
///
/// ```rust
/// use extra::sync::mutex::{StaticMutex, MUTEX_INIT};
/// use sync::mutex::{StaticMutex, MUTEX_INIT};
///
/// static mut LOCK: StaticMutex = MUTEX_INIT;
///

View File

@ -30,7 +30,7 @@ use sync::mutex::{StaticMutex, MUTEX_INIT};
/// # Example
///
/// ```rust
/// use extra::sync::one::{Once, ONCE_INIT};
/// use sync::one::{Once, ONCE_INIT};
///
/// static mut START: Once = ONCE_INIT;
/// unsafe {

View File

@ -16,15 +16,17 @@
// This also serves as a pipes test, because Arcs are implemented with pipes.
extern mod extra;
extern mod sync;
use extra::arc;
use extra::future::Future;
use sync::Arc;
use sync::MutexArc;
use sync::Future;
use extra::time;
use std::os;
use std::uint;
// A poor man's pipe.
type pipe = arc::MutexArc<~[uint]>;
type pipe = MutexArc<~[uint]>;
fn send(p: &pipe, msg: uint) {
unsafe {
@ -46,7 +48,7 @@ fn recv(p: &pipe) -> uint {
}
fn init() -> (pipe,pipe) {
let m = arc::MutexArc::new(~[]);
let m = MutexArc::new(~[]);
((&m).clone(), m)
}

View File

@ -16,15 +16,16 @@
// This also serves as a pipes test, because Arcs are implemented with pipes.
extern mod extra;
extern mod sync;
use extra::arc;
use extra::future::Future;
use sync::RWArc;
use sync::Future;
use extra::time;
use std::os;
use std::uint;
// A poor man's pipe.
type pipe = arc::RWArc<~[uint]>;
type pipe = RWArc<~[uint]>;
fn send(p: &pipe, msg: uint) {
p.write_cond(|state, cond| {
@ -42,7 +43,7 @@ fn recv(p: &pipe) -> uint {
}
fn init() -> (pipe,pipe) {
let x = arc::RWArc::new(~[]);
let x = RWArc::new(~[]);
((&x).clone(), x)
}

View File

@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern mod extra;
extern mod sync;
extern mod arena;
use std::iter::range_step;
use extra::future::Future;
use sync::Future;
use arena::TypedArena;
enum Tree<'a> {

View File

@ -10,15 +10,15 @@
// xfail-test arcs no longer unwrap
extern mod extra;
extern mod sync;
use std::from_str::FromStr;
use std::iter::count;
use std::num::min;
use std::os;
use std::vec::from_elem;
use extra::arc::Arc;
use extra::arc::RWArc;
use sync::Arc;
use sync::RWArc;
fn A(i: uint, j: uint) -> f64 {
((i + j) * (i + j + 1) / 2 + i + 1) as f64

View File

@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern mod extra;
use extra::arc::RWArc;
extern mod sync;
use sync::RWArc;
fn main() {
let arc1 = RWArc::new(true);

View File

@ -9,10 +9,10 @@
// except according to those terms.
// error-pattern: lifetime of return value does not outlive the function call
extern mod extra;
use extra::arc;
extern mod sync;
use sync::RWArc;
fn main() {
let x = ~arc::RWArc::new(1);
let x = ~RWArc::new(1);
let mut y = None;
x.write_cond(|_one, cond| y = Some(cond));
y.unwrap().wait();

View File

@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern mod extra;
use extra::arc;
extern mod sync;
use sync::RWArc;
fn main() {
let x = ~arc::RWArc::new(1);
let x = ~RWArc::new(1);
let mut y = None;
x.write_downgrade(|write_mode| {
y = Some(x.downgrade(write_mode));

View File

@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern mod extra;
use extra::arc;
extern mod sync;
use sync::RWArc;
fn main() {
let x = ~arc::RWArc::new(1);
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;

View File

@ -9,10 +9,10 @@
// except according to those terms.
// error-pattern: lifetime of variable does not enclose its declaration
extern mod extra;
use extra::arc;
extern mod sync;
use sync::RWArc;
fn main() {
let x = ~arc::RWArc::new(1);
let x = ~RWArc::new(1);
let mut y = None;
x.write_downgrade(|write_mode| {
(&write_mode).write_cond(|_one, cond| {

View File

@ -9,10 +9,10 @@
// except according to those terms.
// error-pattern: lifetime of variable does not enclose its declaration
extern mod extra;
use extra::arc;
extern mod sync;
use sync::RWArc;
fn main() {
let x = ~arc::RWArc::new(1);
let x = ~RWArc::new(1);
let mut y = None;
x.write_downgrade(|write_mode| y = Some(write_mode));
y.unwrap();

View File

@ -11,8 +11,8 @@
// issue 7327
// xfail-fast #7103
extern mod extra;
use extra::arc::Arc;
extern mod sync;
use sync::Arc;
struct A { y: Arc<int>, x: Arc<int> }

View File

@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern mod extra;
extern mod sync;
use extra::future::Future;
use sync::Future;
fn main() {
let f = Future::from_value(());

View File

@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern mod extra;
extern mod sync;
use std::task;
use extra::arc::{MutexArc};
use sync::MutexArc;
fn test_mutex_arc_nested() {
let arc = ~MutexArc::new(1);

View File

@ -10,14 +10,14 @@
// error-pattern: use of moved value
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
use std::task;
fn main() {
let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arc_v = arc::Arc::new(v);
let arc_v = Arc::new(v);
task::spawn(proc() {
let v = arc_v.get();

View File

@ -8,14 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
use std::task;
fn main() {
let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arc_v = arc::Arc::new(v);
let arc_v = Arc::new(v);
task::spawn(proc() {
let v = arc_v.get();

View File

@ -12,8 +12,8 @@
// This program would segfault if it were legal.
#[feature(once_fns)];
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
fn foo(blk: proc()) {
blk();
@ -21,7 +21,7 @@ fn foo(blk: proc()) {
}
fn main() {
let x = arc::Arc::new(true);
let x = Arc::new(true);
foo(proc() {
assert!(*x.get());
drop(x);

View File

@ -12,8 +12,8 @@
// This program would segfault if it were legal.
#[feature(once_fns)];
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
fn foo(blk: once ||) {
blk();
@ -21,7 +21,7 @@ fn foo(blk: once ||) {
}
fn main() {
let x = arc::Arc::new(true);
let x = Arc::new(true);
foo(|| {
assert!(*x.get());
drop(x);

View File

@ -11,8 +11,8 @@
// Testing guarantees provided by once functions.
// This program would segfault if it were legal.
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
fn foo(blk: ||) {
blk();
@ -20,7 +20,7 @@ fn foo(blk: ||) {
}
fn main() {
let x = arc::Arc::new(true);
let x = Arc::new(true);
foo(|| {
assert!(*x.get());
drop(x); //~ ERROR cannot move out of captured outer variable

View File

@ -9,8 +9,8 @@
// except according to those terms.
// error-pattern: lifetime of variable does not enclose its declaration
extern mod extra;
use extra::sync;
extern mod sync;
use sync::Mutex;
fn main() {
let m = ~sync::Mutex::new();

View File

@ -9,10 +9,10 @@
// except according to those terms.
// error-pattern: lifetime of method receiver does not outlive the method call
extern mod extra;
use extra::sync;
extern mod sync;
use sync::RWLock;
fn main() {
let x = ~sync::RWLock::new();
let x = ~RWLock::new();
let mut y = None;
x.write_cond(|cond| {
y = Some(cond);

View File

@ -9,10 +9,10 @@
// except according to those terms.
// error-pattern: cannot infer an appropriate lifetime
extern mod extra;
use extra::sync;
extern mod sync;
use sync::RWLock;
fn main() {
let x = ~sync::RWLock::new();
let x = ~RWLock::new();
let mut y = None;
x.write_downgrade(|write_mode| {
y = Some(x.downgrade(write_mode));

View File

@ -9,10 +9,10 @@
// except according to those terms.
// error-pattern: lifetime of variable does not enclose its declaration
extern mod extra;
use extra::sync;
extern mod sync;
use sync::RWLock;
fn main() {
let x = ~sync::RWLock::new();
let x = ~RWLock::new();
let mut y = None;
x.write_downgrade(|write_mode| {
(&write_mode).write_cond(|cond| {

View File

@ -9,10 +9,10 @@
// except according to those terms.
// error-pattern: lifetime of variable does not enclose its declaration
extern mod extra;
use extra::sync;
extern mod sync;
use sync::RWLock;
fn main() {
let x = ~sync::RWLock::new();
let x = ~RWLock::new();
let mut y = None;
x.write_downgrade(|write_mode| {
y = Some(write_mode);

View File

@ -10,10 +10,10 @@
// error-pattern:explicit failure
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
enum e<T> { e(arc::Arc<T>) }
enum e<T> { e(Arc<T>) }
fn foo() -> e<int> {fail!();}

View File

@ -9,12 +9,12 @@
// except according to those terms.
// xfail-fast
extern mod extra;
use extra::arc;
fn dispose(_x: arc::Arc<bool>) { }
extern mod sync;
use sync::Arc;
fn dispose(_x: Arc<bool>) { }
pub fn main() {
let p = arc::Arc::new(true);
let p = Arc::new(true);
let x = Some(p);
match x {
Some(z) => { dispose(z); },

View File

@ -13,15 +13,15 @@
// xfail-fast
#[feature(once_fns)];
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
fn foo(blk: proc()) {
blk();
}
pub fn main() {
let x = arc::Arc::new(true);
let x = Arc::new(true);
foo(proc() {
assert!(*x.get());
drop(x);

View File

@ -13,15 +13,15 @@
// xfail-fast
#[feature(once_fns)];
extern mod extra;
use extra::arc;
extern mod sync;
use sync::Arc;
fn foo(blk: once ||) {
blk();
}
pub fn main() {
let x = arc::Arc::new(true);
let x = Arc::new(true);
foo(|| {
assert!(*x.get());
drop(x);

View File

@ -15,9 +15,9 @@
// xfail-fast
extern mod extra;
extern mod sync;
use extra::arc;
use sync::Arc;
use std::task;
trait Pet {
@ -65,7 +65,7 @@ pub fn main() {
let dogge1 = Dogge { bark_decibels: 100, tricks_known: 42, name: ~"alan_turing" };
let dogge2 = Dogge { bark_decibels: 55, tricks_known: 11, name: ~"albert_einstein" };
let fishe = Goldfyshe { swim_speed: 998, name: ~"alec_guinness" };
let arc = arc::Arc::new(~[~catte as ~Pet:Freeze+Send,
let arc = Arc::new(~[~catte as ~Pet:Freeze+Send,
~dogge1 as ~Pet:Freeze+Send,
~fishe as ~Pet:Freeze+Send,
~dogge2 as ~Pet:Freeze+Send]);
@ -83,21 +83,21 @@ pub fn main() {
p3.recv();
}
fn check_legs(arc: arc::Arc<~[~Pet:Freeze+Send]>) {
fn check_legs(arc: Arc<~[~Pet:Freeze+Send]>) {
let mut legs = 0;
for pet in arc.get().iter() {
legs += pet.num_legs();
}
assert!(legs == 12);
}
fn check_names(arc: arc::Arc<~[~Pet:Freeze+Send]>) {
fn check_names(arc: Arc<~[~Pet:Freeze+Send]>) {
for pet in arc.get().iter() {
pet.name(|name| {
assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8);
})
}
}
fn check_pedigree(arc: arc::Arc<~[~Pet:Freeze+Send]>) {
fn check_pedigree(arc: Arc<~[~Pet:Freeze+Send]>) {
for pet in arc.get().iter() {
assert!(pet.of_good_pedigree());
}