move concurrent stuff from libextra to libsync
This commit is contained in:
parent
ed885e35fe
commit
dd21a51d29
48 changed files with 224 additions and 145 deletions
|
@ -49,25 +49,26 @@
|
||||||
# automatically generated for all stage/host/target combinations.
|
# 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
|
HOST_CRATES := syntax rustc rustdoc
|
||||||
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
|
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
|
||||||
TOOLS := compiletest rustdoc rustc
|
TOOLS := compiletest rustdoc rustc
|
||||||
|
|
||||||
DEPS_std := native:rustrt
|
DEPS_std := native:rustrt
|
||||||
DEPS_extra := std term
|
DEPS_extra := std term sync
|
||||||
DEPS_green := std
|
DEPS_green := std
|
||||||
DEPS_rustuv := std native:uv native:uv_support
|
DEPS_rustuv := std native:uv native:uv_support
|
||||||
DEPS_native := std
|
DEPS_native := std
|
||||||
DEPS_syntax := std extra term
|
DEPS_syntax := std extra term
|
||||||
DEPS_rustc := syntax native:rustllvm flate arena
|
DEPS_rustc := syntax native:rustllvm flate arena sync
|
||||||
DEPS_rustdoc := rustc native:sundown
|
DEPS_rustdoc := rustc native:sundown sync
|
||||||
DEPS_flate := std native:miniz
|
DEPS_flate := std native:miniz
|
||||||
DEPS_arena := std extra
|
DEPS_arena := std extra
|
||||||
DEPS_glob := std
|
DEPS_glob := std
|
||||||
DEPS_term := std
|
DEPS_term := std
|
||||||
DEPS_semver := std
|
DEPS_semver := std
|
||||||
DEPS_uuid := std extra
|
DEPS_uuid := std extra
|
||||||
|
DEPS_sync := std
|
||||||
|
|
||||||
TOOL_DEPS_compiletest := extra green rustuv
|
TOOL_DEPS_compiletest := extra green rustuv
|
||||||
TOOL_DEPS_rustdoc := rustdoc green rustuv
|
TOOL_DEPS_rustdoc := rustdoc green rustuv
|
||||||
|
|
|
@ -39,7 +39,7 @@ data through the global _exchange heap_.
|
||||||
|
|
||||||
While Rust's type system provides the building blocks needed for safe
|
While Rust's type system provides the building blocks needed for safe
|
||||||
and efficient tasks, all of the task functionality itself is implemented
|
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.
|
and do not always present a consistent or complete interface.
|
||||||
|
|
||||||
For your reference, these are the standard modules involved in Rust
|
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::task`] - All code relating to tasks and task scheduling,
|
||||||
* [`std::comm`] - The message passing interface,
|
* [`std::comm`] - The message passing interface,
|
||||||
* [`extra::comm`] - Additional messaging types based on `std::comm`,
|
* [`sync::DuplexStream`] - An extension of `pipes::stream` that allows both sending and receiving,
|
||||||
* [`extra::sync`] - More exotic synchronization tools, including locks,
|
* [`sync::SyncChan`] - An extension of `pipes::stream` that provides synchronous message sending,
|
||||||
* [`extra::arc`] - The Arc (atomically reference counted) type,
|
* [`sync::SyncPort`] - An extension of `pipes::stream` that acknowledges each message received,
|
||||||
for safely sharing immutable data,
|
* [`sync::rendezvous`] - Creates a stream whose channel, upon sending a message, blocks until the
|
||||||
* [`extra::future`] - A type representing values that may be computed concurrently and retrieved at a later time.
|
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::task`]: std/task/index.html
|
||||||
[`std::comm`]: std/comm/index.html
|
[`std::comm`]: std/comm/index.html
|
||||||
[`extra::comm`]: extra/comm/index.html
|
[`sync::DuplexStream`]: sync/struct.DuplexStream.html
|
||||||
[`extra::sync`]: extra/sync/index.html
|
[`sync::SyncChan`]: sync/struct.SyncChan.html
|
||||||
[`extra::arc`]: extra/arc/index.html
|
[`sync::SyncPort`]: sync/struct.SyncPort.html
|
||||||
[`extra::future`]: extra/future/index.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
|
# Basics
|
||||||
|
|
||||||
|
@ -254,21 +279,25 @@ let result = ports.iter().fold(0, |accum, port| accum + port.recv() );
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
## Backgrounding computations: Futures
|
## 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.
|
later.
|
||||||
|
|
||||||
The basic example below illustrates this.
|
The basic example below illustrates this.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
# extern mod sync;
|
||||||
|
|
||||||
|
# fn main() {
|
||||||
# fn make_a_sandwich() {};
|
# fn make_a_sandwich() {};
|
||||||
fn fib(n: u64) -> u64 {
|
fn fib(n: u64) -> u64 {
|
||||||
// lengthy computation returning an uint
|
// lengthy computation returning an uint
|
||||||
12586269025
|
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();
|
make_a_sandwich();
|
||||||
println!("fib(50) = {:?}", delayed_fib.get())
|
println!("fib(50) = {:?}", delayed_fib.get())
|
||||||
|
# }
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
The call to `future::spawn` returns immediately a `future` object regardless of how long it
|
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.
|
be distributed on the available cores.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
# extern mod sync;
|
||||||
# use std::vec;
|
# use std::vec;
|
||||||
fn partial_sum(start: uint) -> f64 {
|
fn partial_sum(start: uint) -> f64 {
|
||||||
let mut local_sum = 0f64;
|
let mut local_sum = 0f64;
|
||||||
|
@ -291,7 +321,7 @@ fn partial_sum(start: uint) -> f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
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;
|
let mut final_res = 0f64;
|
||||||
for ft in futures.mut_iter() {
|
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.
|
necessary.
|
||||||
|
|
||||||
To tackle this issue, one can use an Atomically Reference Counted wrapper (`Arc`) as implemented in
|
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.
|
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
|
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.
|
a single large vector of floats. Each task needs the full vector to perform its duty.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
# extern mod sync;
|
||||||
# use std::vec;
|
# use std::vec;
|
||||||
# use std::rand;
|
# use std::rand;
|
||||||
use extra::arc::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
fn pnorm(nums: &~[f64], p: uint) -> f64 {
|
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)))
|
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
|
created by the line
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
# use extra::arc::Arc;
|
# extern mod sync;
|
||||||
|
# use sync::Arc;
|
||||||
# use std::vec;
|
# use std::vec;
|
||||||
# use std::rand;
|
# use std::rand;
|
||||||
|
# fn main() {
|
||||||
# let numbers = vec::from_fn(1000000, |_| rand::random::<f64>());
|
# let numbers = vec::from_fn(1000000, |_| rand::random::<f64>());
|
||||||
let numbers_arc=Arc::new(numbers);
|
let numbers_arc=Arc::new(numbers);
|
||||||
|
# }
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
and a clone of it is sent to each task
|
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::vec;
|
||||||
# use std::rand;
|
# use std::rand;
|
||||||
|
# fn main() {
|
||||||
# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
|
# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
|
||||||
# let numbers_arc = Arc::new(numbers);
|
# let numbers_arc = Arc::new(numbers);
|
||||||
# let (port, chan) = Chan::new();
|
# let (port, chan) = Chan::new();
|
||||||
chan.send(numbers_arc.clone());
|
chan.send(numbers_arc.clone());
|
||||||
|
# }
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
copying only the wrapper and not its contents.
|
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
|
Each task recovers the underlying data by
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
# use extra::arc::Arc;
|
# extern mod sync;
|
||||||
|
# use sync::Arc;
|
||||||
# use std::vec;
|
# use std::vec;
|
||||||
# use std::rand;
|
# use std::rand;
|
||||||
|
# fn main() {
|
||||||
# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
|
# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
|
||||||
# let numbers_arc=Arc::new(numbers);
|
# let numbers_arc=Arc::new(numbers);
|
||||||
# let (port, chan) = Chan::new();
|
# let (port, chan) = Chan::new();
|
||||||
# chan.send(numbers_arc.clone());
|
# chan.send(numbers_arc.clone());
|
||||||
# let local_arc : Arc<~[f64]> = port.recv();
|
# let local_arc : Arc<~[f64]> = port.recv();
|
||||||
let task_numbers = local_arc.get();
|
let task_numbers = local_arc.get();
|
||||||
|
# }
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
and can use it as if it were local.
|
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
|
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
|
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.
|
look briefly at how to use it.
|
||||||
|
|
||||||
To see how `DuplexStream()` works, we will create a child task
|
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`.
|
the string in response. The child terminates when it receives `0`.
|
||||||
Here is the function that implements the child task:
|
Here is the function that implements the child task:
|
||||||
|
|
||||||
~~~{.ignore .linked-failure}
|
~~~
|
||||||
# use extra::comm::DuplexStream;
|
# extern mod sync;
|
||||||
# use std::uint;
|
# fn main() {
|
||||||
fn stringifier(channel: &DuplexStream<~str, uint>) {
|
# use sync::DuplexStream;
|
||||||
|
fn stringifier(channel: &DuplexStream<~str, uint>) {
|
||||||
let mut value: uint;
|
let mut value: uint;
|
||||||
loop {
|
loop {
|
||||||
value = channel.recv();
|
value = channel.recv();
|
||||||
channel.send(uint::to_str(value));
|
channel.send(value.to_str());
|
||||||
if value == 0 { break; }
|
if value == 0 { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# }
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
The implementation of `DuplexStream` supports both sending and
|
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:
|
Here is the code for the parent task:
|
||||||
|
|
||||||
~~~{.ignore .linked-failure}
|
~~~
|
||||||
|
# extern mod sync;
|
||||||
# use std::task::spawn;
|
# use std::task::spawn;
|
||||||
# use std::uint;
|
# use sync::DuplexStream;
|
||||||
# use extra::comm::DuplexStream;
|
|
||||||
# fn stringifier(channel: &DuplexStream<~str, uint>) {
|
# fn stringifier(channel: &DuplexStream<~str, uint>) {
|
||||||
# let mut value: uint;
|
# let mut value: uint;
|
||||||
# loop {
|
# loop {
|
||||||
# value = channel.recv();
|
# value = channel.recv();
|
||||||
# channel.send(uint::to_str(value));
|
# channel.send(value.to_str());
|
||||||
# if value == 0u { break; }
|
# if value == 0u { break; }
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
|
|
|
@ -43,6 +43,7 @@ li {list-style-type: none; }
|
||||||
* [The `semver` version collation library](semver/index.html)
|
* [The `semver` version collation library](semver/index.html)
|
||||||
* [The `term` terminal-handling library](term/index.html)
|
* [The `term` terminal-handling library](term/index.html)
|
||||||
* [The UUID library](uuid/index.html)
|
* [The UUID library](uuid/index.html)
|
||||||
|
* [The `sync` library for concurrency-enabled mechanisms and primitives](sync/index.html)
|
||||||
|
|
||||||
# Tooling
|
# Tooling
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ exceptions = [
|
||||||
"libstd/sync/mpsc_queue.rs", # BSD
|
"libstd/sync/mpsc_queue.rs", # BSD
|
||||||
"libstd/sync/spsc_queue.rs", # BSD
|
"libstd/sync/spsc_queue.rs", # BSD
|
||||||
"libstd/sync/mpmc_bounded_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):
|
def check_license(name, contents):
|
||||||
|
|
|
@ -34,18 +34,17 @@ Rust extras are part of the standard Rust distribution.
|
||||||
#[deny(non_camel_case_types)];
|
#[deny(non_camel_case_types)];
|
||||||
#[deny(missing_doc)];
|
#[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
|
// Utility modules
|
||||||
|
|
||||||
pub mod c_vec;
|
pub mod c_vec;
|
||||||
|
|
||||||
// Concurrency
|
|
||||||
|
|
||||||
pub mod sync;
|
|
||||||
pub mod arc;
|
|
||||||
pub mod comm;
|
|
||||||
pub mod future;
|
|
||||||
pub mod task_pool;
|
|
||||||
|
|
||||||
// Collections
|
// Collections
|
||||||
|
|
||||||
pub mod container;
|
pub mod container;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
use json;
|
use json;
|
||||||
use json::ToJson;
|
use json::ToJson;
|
||||||
use serialize::{Encoder, Encodable, Decoder, Decodable};
|
use serialize::{Encoder, Encodable, Decoder, Decodable};
|
||||||
use arc::{Arc,RWArc};
|
use sync::{Arc,RWArc};
|
||||||
use treemap::TreeMap;
|
use treemap::TreeMap;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
|
@ -331,7 +331,7 @@ pub mod write {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn configure_llvm(sess: Session) {
|
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;
|
static mut INIT: Once = ONCE_INIT;
|
||||||
|
|
||||||
// Copy what clang does by turning on loop vectorization at O2 and
|
// Copy what clang does by turning on loop vectorization at O2 and
|
||||||
|
|
|
@ -35,6 +35,7 @@ extern mod extra;
|
||||||
extern mod flate;
|
extern mod flate;
|
||||||
extern mod arena;
|
extern mod arena;
|
||||||
extern mod syntax;
|
extern mod syntax;
|
||||||
|
extern mod sync;
|
||||||
|
|
||||||
use back::link;
|
use back::link;
|
||||||
use driver::session;
|
use driver::session;
|
||||||
|
|
|
@ -2660,7 +2660,7 @@ pub fn trans_crate(sess: session::Session,
|
||||||
output: &Path) -> CrateTranslation {
|
output: &Path) -> CrateTranslation {
|
||||||
// Before we touch LLVM, make sure that multithreading is enabled.
|
// Before we touch LLVM, make sure that multithreading is enabled.
|
||||||
unsafe {
|
unsafe {
|
||||||
use extra::sync::one::{Once, ONCE_INIT};
|
use sync::one::{Once, ONCE_INIT};
|
||||||
static mut INIT: Once = ONCE_INIT;
|
static mut INIT: Once = ONCE_INIT;
|
||||||
static mut POISONED: bool = false;
|
static mut POISONED: bool = false;
|
||||||
INIT.doit(|| {
|
INIT.doit(|| {
|
||||||
|
|
|
@ -41,7 +41,7 @@ use std::io::{fs, File, BufferedWriter};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
use extra::arc::Arc;
|
use sync::Arc;
|
||||||
use extra::json::ToJson;
|
use extra::json::ToJson;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
extern mod syntax;
|
extern mod syntax;
|
||||||
extern mod rustc;
|
extern mod rustc;
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
extern mod sync;
|
||||||
|
|
||||||
use std::local_data;
|
use std::local_data;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* With simple pipes, without Arc, a copy would have to be made for each task.
|
* With simple pipes, without Arc, a copy would have to be made for each task.
|
||||||
*
|
*
|
||||||
* ```rust
|
* ```rust
|
||||||
* use extra::arc::Arc;
|
* use sync::Arc;
|
||||||
* use std::{rand, vec};
|
* use std::{rand, vec};
|
||||||
*
|
*
|
||||||
* let numbers = vec::from_fn(100, |i| (i as f32) * rand::random());
|
* 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;
|
use sync;
|
||||||
|
@ -424,7 +424,7 @@ impl<T:Freeze + Send> RWArc<T> {
|
||||||
* # Example
|
* # Example
|
||||||
*
|
*
|
||||||
* ```rust
|
* ```rust
|
||||||
* use extra::arc::RWArc;
|
* use sync::RWArc;
|
||||||
*
|
*
|
||||||
* let arc = RWArc::new(1);
|
* let arc = RWArc::new(1);
|
||||||
* arc.write_downgrade(|mut write_token| {
|
* arc.write_downgrade(|mut write_token| {
|
||||||
|
@ -605,7 +605,7 @@ impl<T:Clone+Send+Freeze> Clone for CowArc<T> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use arc::*;
|
use super::{Arc, RWArc, MutexArc, CowArc};
|
||||||
|
|
||||||
use std::task;
|
use std::task;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* # Example
|
* # Example
|
||||||
*
|
*
|
||||||
* ```rust
|
* ```rust
|
||||||
* use extra::future::Future;
|
* use sync::Future;
|
||||||
* # fn fib(n: uint) -> uint {42};
|
* # fn fib(n: uint) -> uint {42};
|
||||||
* # fn make_a_sandwich() {};
|
* # fn make_a_sandwich() {};
|
||||||
* let mut delayed_fib = Future::spawn(proc() { fib(5000) });
|
* let mut delayed_fib = Future::spawn(proc() { fib(5000) });
|
31
src/libsync/lib.rs
Normal file
31
src/libsync/lib.rs
Normal 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;
|
|
@ -588,7 +588,7 @@ impl RWLock {
|
||||||
* # Example
|
* # Example
|
||||||
*
|
*
|
||||||
* ```rust
|
* ```rust
|
||||||
* use extra::sync::RWLock;
|
* use sync::RWLock;
|
||||||
*
|
*
|
||||||
* let lock = RWLock::new();
|
* let lock = RWLock::new();
|
||||||
* lock.write_downgrade(|mut write_token| {
|
* lock.write_downgrade(|mut write_token| {
|
||||||
|
@ -695,7 +695,7 @@ impl<'a> RWLockReadMode<'a> {
|
||||||
/// of some computation.
|
/// of some computation.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use extra::sync::Barrier;
|
/// use sync::Barrier;
|
||||||
///
|
///
|
||||||
/// let barrier = Barrier::new(10);
|
/// let barrier = Barrier::new(10);
|
||||||
/// for _ in range(0, 10) {
|
/// for _ in range(0, 10) {
|
||||||
|
@ -759,7 +759,7 @@ impl Barrier {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use sync::*;
|
use sync::{Semaphore, Mutex, RWLock, Barrier, Condvar};
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::result;
|
use std::result;
|
|
@ -83,7 +83,7 @@ pub static NATIVE_BLOCKED: uint = 1 << 2;
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use extra::sync::mutex::Mutex;
|
/// use sync::mutex::Mutex;
|
||||||
///
|
///
|
||||||
/// let mut m = Mutex::new();
|
/// let mut m = Mutex::new();
|
||||||
/// let guard = m.lock();
|
/// let guard = m.lock();
|
||||||
|
@ -113,7 +113,7 @@ enum Flavor {
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use extra::sync::mutex::{StaticMutex, MUTEX_INIT};
|
/// use sync::mutex::{StaticMutex, MUTEX_INIT};
|
||||||
///
|
///
|
||||||
/// static mut LOCK: StaticMutex = MUTEX_INIT;
|
/// static mut LOCK: StaticMutex = MUTEX_INIT;
|
||||||
///
|
///
|
|
@ -30,7 +30,7 @@ use sync::mutex::{StaticMutex, MUTEX_INIT};
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use extra::sync::one::{Once, ONCE_INIT};
|
/// use sync::one::{Once, ONCE_INIT};
|
||||||
///
|
///
|
||||||
/// static mut START: Once = ONCE_INIT;
|
/// static mut START: Once = ONCE_INIT;
|
||||||
/// unsafe {
|
/// unsafe {
|
|
@ -16,15 +16,17 @@
|
||||||
// This also serves as a pipes test, because Arcs are implemented with pipes.
|
// This also serves as a pipes test, because Arcs are implemented with pipes.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
extern mod sync;
|
||||||
|
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
use extra::future::Future;
|
use sync::MutexArc;
|
||||||
|
use sync::Future;
|
||||||
use extra::time;
|
use extra::time;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
|
|
||||||
// A poor man's pipe.
|
// A poor man's pipe.
|
||||||
type pipe = arc::MutexArc<~[uint]>;
|
type pipe = MutexArc<~[uint]>;
|
||||||
|
|
||||||
fn send(p: &pipe, msg: uint) {
|
fn send(p: &pipe, msg: uint) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -46,7 +48,7 @@ fn recv(p: &pipe) -> uint {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init() -> (pipe,pipe) {
|
fn init() -> (pipe,pipe) {
|
||||||
let m = arc::MutexArc::new(~[]);
|
let m = MutexArc::new(~[]);
|
||||||
((&m).clone(), m)
|
((&m).clone(), m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,16 @@
|
||||||
// This also serves as a pipes test, because Arcs are implemented with pipes.
|
// This also serves as a pipes test, because Arcs are implemented with pipes.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
extern mod sync;
|
||||||
|
|
||||||
use extra::arc;
|
use sync::RWArc;
|
||||||
use extra::future::Future;
|
use sync::Future;
|
||||||
use extra::time;
|
use extra::time;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
|
|
||||||
// A poor man's pipe.
|
// A poor man's pipe.
|
||||||
type pipe = arc::RWArc<~[uint]>;
|
type pipe = RWArc<~[uint]>;
|
||||||
|
|
||||||
fn send(p: &pipe, msg: uint) {
|
fn send(p: &pipe, msg: uint) {
|
||||||
p.write_cond(|state, cond| {
|
p.write_cond(|state, cond| {
|
||||||
|
@ -42,7 +43,7 @@ fn recv(p: &pipe) -> uint {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init() -> (pipe,pipe) {
|
fn init() -> (pipe,pipe) {
|
||||||
let x = arc::RWArc::new(~[]);
|
let x = RWArc::new(~[]);
|
||||||
((&x).clone(), x)
|
((&x).clone(), x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
extern mod arena;
|
extern mod arena;
|
||||||
|
|
||||||
use std::iter::range_step;
|
use std::iter::range_step;
|
||||||
use extra::future::Future;
|
use sync::Future;
|
||||||
use arena::TypedArena;
|
use arena::TypedArena;
|
||||||
|
|
||||||
enum Tree<'a> {
|
enum Tree<'a> {
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
|
|
||||||
// xfail-test arcs no longer unwrap
|
// xfail-test arcs no longer unwrap
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
|
|
||||||
use std::from_str::FromStr;
|
use std::from_str::FromStr;
|
||||||
use std::iter::count;
|
use std::iter::count;
|
||||||
use std::num::min;
|
use std::num::min;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::vec::from_elem;
|
use std::vec::from_elem;
|
||||||
use extra::arc::Arc;
|
use sync::Arc;
|
||||||
use extra::arc::RWArc;
|
use sync::RWArc;
|
||||||
|
|
||||||
fn A(i: uint, j: uint) -> f64 {
|
fn A(i: uint, j: uint) -> f64 {
|
||||||
((i + j) * (i + j + 1) / 2 + i + 1) as f64
|
((i + j) * (i + j + 1) / 2 + i + 1) as f64
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc::RWArc;
|
use sync::RWArc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let arc1 = RWArc::new(true);
|
let arc1 = RWArc::new(true);
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: lifetime of return value does not outlive the function call
|
// error-pattern: lifetime of return value does not outlive the function call
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::RWArc;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~arc::RWArc::new(1);
|
let x = ~RWArc::new(1);
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_cond(|_one, cond| y = Some(cond));
|
x.write_cond(|_one, cond| y = Some(cond));
|
||||||
y.unwrap().wait();
|
y.unwrap().wait();
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::RWArc;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~arc::RWArc::new(1);
|
let x = ~RWArc::new(1);
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_downgrade(|write_mode| {
|
x.write_downgrade(|write_mode| {
|
||||||
y = Some(x.downgrade(write_mode));
|
y = Some(x.downgrade(write_mode));
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::RWArc;
|
||||||
fn main() {
|
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
|
let mut y = None; //~ ERROR lifetime of variable does not enclose its declaration
|
||||||
x.write(|one| y = Some(one));
|
x.write(|one| y = Some(one));
|
||||||
*y.unwrap() = 2;
|
*y.unwrap() = 2;
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: lifetime of variable does not enclose its declaration
|
// error-pattern: lifetime of variable does not enclose its declaration
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::RWArc;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~arc::RWArc::new(1);
|
let x = ~RWArc::new(1);
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_downgrade(|write_mode| {
|
x.write_downgrade(|write_mode| {
|
||||||
(&write_mode).write_cond(|_one, cond| {
|
(&write_mode).write_cond(|_one, cond| {
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: lifetime of variable does not enclose its declaration
|
// error-pattern: lifetime of variable does not enclose its declaration
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::RWArc;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~arc::RWArc::new(1);
|
let x = ~RWArc::new(1);
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_downgrade(|write_mode| y = Some(write_mode));
|
x.write_downgrade(|write_mode| y = Some(write_mode));
|
||||||
y.unwrap();
|
y.unwrap();
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
// issue 7327
|
// issue 7327
|
||||||
|
|
||||||
// xfail-fast #7103
|
// xfail-fast #7103
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
struct A { y: Arc<int>, x: Arc<int> }
|
struct A { y: Arc<int>, x: Arc<int> }
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
|
|
||||||
use extra::future::Future;
|
use sync::Future;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let f = Future::from_value(());
|
let f = Future::from_value(());
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
|
|
||||||
use std::task;
|
use std::task;
|
||||||
use extra::arc::{MutexArc};
|
use sync::MutexArc;
|
||||||
|
|
||||||
fn test_mutex_arc_nested() {
|
fn test_mutex_arc_nested() {
|
||||||
let arc = ~MutexArc::new(1);
|
let arc = ~MutexArc::new(1);
|
||||||
|
|
|
@ -10,14 +10,14 @@
|
||||||
|
|
||||||
// error-pattern: use of moved value
|
// error-pattern: use of moved value
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
use std::task;
|
use std::task;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
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() {
|
task::spawn(proc() {
|
||||||
let v = arc_v.get();
|
let v = arc_v.get();
|
||||||
|
|
|
@ -8,14 +8,14 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
use std::task;
|
use std::task;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
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() {
|
task::spawn(proc() {
|
||||||
let v = arc_v.get();
|
let v = arc_v.get();
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
// This program would segfault if it were legal.
|
// This program would segfault if it were legal.
|
||||||
|
|
||||||
#[feature(once_fns)];
|
#[feature(once_fns)];
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
fn foo(blk: proc()) {
|
fn foo(blk: proc()) {
|
||||||
blk();
|
blk();
|
||||||
|
@ -21,7 +21,7 @@ fn foo(blk: proc()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = arc::Arc::new(true);
|
let x = Arc::new(true);
|
||||||
foo(proc() {
|
foo(proc() {
|
||||||
assert!(*x.get());
|
assert!(*x.get());
|
||||||
drop(x);
|
drop(x);
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
// This program would segfault if it were legal.
|
// This program would segfault if it were legal.
|
||||||
|
|
||||||
#[feature(once_fns)];
|
#[feature(once_fns)];
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
fn foo(blk: once ||) {
|
fn foo(blk: once ||) {
|
||||||
blk();
|
blk();
|
||||||
|
@ -21,7 +21,7 @@ fn foo(blk: once ||) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = arc::Arc::new(true);
|
let x = Arc::new(true);
|
||||||
foo(|| {
|
foo(|| {
|
||||||
assert!(*x.get());
|
assert!(*x.get());
|
||||||
drop(x);
|
drop(x);
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
// Testing guarantees provided by once functions.
|
// Testing guarantees provided by once functions.
|
||||||
// This program would segfault if it were legal.
|
// This program would segfault if it were legal.
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
fn foo(blk: ||) {
|
fn foo(blk: ||) {
|
||||||
blk();
|
blk();
|
||||||
|
@ -20,7 +20,7 @@ fn foo(blk: ||) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = arc::Arc::new(true);
|
let x = Arc::new(true);
|
||||||
foo(|| {
|
foo(|| {
|
||||||
assert!(*x.get());
|
assert!(*x.get());
|
||||||
drop(x); //~ ERROR cannot move out of captured outer variable
|
drop(x); //~ ERROR cannot move out of captured outer variable
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: lifetime of variable does not enclose its declaration
|
// error-pattern: lifetime of variable does not enclose its declaration
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::sync;
|
use sync::Mutex;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let m = ~sync::Mutex::new();
|
let m = ~sync::Mutex::new();
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: lifetime of method receiver does not outlive the method call
|
// error-pattern: lifetime of method receiver does not outlive the method call
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::sync;
|
use sync::RWLock;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~sync::RWLock::new();
|
let x = ~RWLock::new();
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_cond(|cond| {
|
x.write_cond(|cond| {
|
||||||
y = Some(cond);
|
y = Some(cond);
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: cannot infer an appropriate lifetime
|
// error-pattern: cannot infer an appropriate lifetime
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::sync;
|
use sync::RWLock;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~sync::RWLock::new();
|
let x = ~RWLock::new();
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_downgrade(|write_mode| {
|
x.write_downgrade(|write_mode| {
|
||||||
y = Some(x.downgrade(write_mode));
|
y = Some(x.downgrade(write_mode));
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: lifetime of variable does not enclose its declaration
|
// error-pattern: lifetime of variable does not enclose its declaration
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::sync;
|
use sync::RWLock;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~sync::RWLock::new();
|
let x = ~RWLock::new();
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_downgrade(|write_mode| {
|
x.write_downgrade(|write_mode| {
|
||||||
(&write_mode).write_cond(|cond| {
|
(&write_mode).write_cond(|cond| {
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// error-pattern: lifetime of variable does not enclose its declaration
|
// error-pattern: lifetime of variable does not enclose its declaration
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::sync;
|
use sync::RWLock;
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~sync::RWLock::new();
|
let x = ~RWLock::new();
|
||||||
let mut y = None;
|
let mut y = None;
|
||||||
x.write_downgrade(|write_mode| {
|
x.write_downgrade(|write_mode| {
|
||||||
y = Some(write_mode);
|
y = Some(write_mode);
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
// error-pattern:explicit failure
|
// error-pattern:explicit failure
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
enum e<T> { e(arc::Arc<T>) }
|
enum e<T> { e(Arc<T>) }
|
||||||
|
|
||||||
fn foo() -> e<int> {fail!();}
|
fn foo() -> e<int> {fail!();}
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
fn dispose(_x: arc::Arc<bool>) { }
|
fn dispose(_x: Arc<bool>) { }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let p = arc::Arc::new(true);
|
let p = Arc::new(true);
|
||||||
let x = Some(p);
|
let x = Some(p);
|
||||||
match x {
|
match x {
|
||||||
Some(z) => { dispose(z); },
|
Some(z) => { dispose(z); },
|
||||||
|
|
|
@ -13,15 +13,15 @@
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
|
|
||||||
#[feature(once_fns)];
|
#[feature(once_fns)];
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
fn foo(blk: proc()) {
|
fn foo(blk: proc()) {
|
||||||
blk();
|
blk();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let x = arc::Arc::new(true);
|
let x = Arc::new(true);
|
||||||
foo(proc() {
|
foo(proc() {
|
||||||
assert!(*x.get());
|
assert!(*x.get());
|
||||||
drop(x);
|
drop(x);
|
||||||
|
|
|
@ -13,15 +13,15 @@
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
|
|
||||||
#[feature(once_fns)];
|
#[feature(once_fns)];
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
|
|
||||||
fn foo(blk: once ||) {
|
fn foo(blk: once ||) {
|
||||||
blk();
|
blk();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let x = arc::Arc::new(true);
|
let x = Arc::new(true);
|
||||||
foo(|| {
|
foo(|| {
|
||||||
assert!(*x.get());
|
assert!(*x.get());
|
||||||
drop(x);
|
drop(x);
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
|
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
|
|
||||||
extern mod extra;
|
extern mod sync;
|
||||||
|
|
||||||
use extra::arc;
|
use sync::Arc;
|
||||||
use std::task;
|
use std::task;
|
||||||
|
|
||||||
trait Pet {
|
trait Pet {
|
||||||
|
@ -65,7 +65,7 @@ pub fn main() {
|
||||||
let dogge1 = Dogge { bark_decibels: 100, tricks_known: 42, name: ~"alan_turing" };
|
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 dogge2 = Dogge { bark_decibels: 55, tricks_known: 11, name: ~"albert_einstein" };
|
||||||
let fishe = Goldfyshe { swim_speed: 998, name: ~"alec_guinness" };
|
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,
|
~dogge1 as ~Pet:Freeze+Send,
|
||||||
~fishe as ~Pet:Freeze+Send,
|
~fishe as ~Pet:Freeze+Send,
|
||||||
~dogge2 as ~Pet:Freeze+Send]);
|
~dogge2 as ~Pet:Freeze+Send]);
|
||||||
|
@ -83,21 +83,21 @@ pub fn main() {
|
||||||
p3.recv();
|
p3.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_legs(arc: arc::Arc<~[~Pet:Freeze+Send]>) {
|
fn check_legs(arc: Arc<~[~Pet:Freeze+Send]>) {
|
||||||
let mut legs = 0;
|
let mut legs = 0;
|
||||||
for pet in arc.get().iter() {
|
for pet in arc.get().iter() {
|
||||||
legs += pet.num_legs();
|
legs += pet.num_legs();
|
||||||
}
|
}
|
||||||
assert!(legs == 12);
|
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() {
|
for pet in arc.get().iter() {
|
||||||
pet.name(|name| {
|
pet.name(|name| {
|
||||||
assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8);
|
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() {
|
for pet in arc.get().iter() {
|
||||||
assert!(pet.of_good_pedigree());
|
assert!(pet.of_good_pedigree());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue