std: Rename Chan/Port types and constructor

* Chan<T> => Sender<T>
* Port<T> => Receiver<T>
* Chan::new() => channel()
* constructor returns (Sender, Receiver) instead of (Receiver, Sender)
* local variables named `port` renamed to `rx`
* local variables named `chan` renamed to `tx`

Closes #11765
This commit is contained in:
Alex Crichton 2014-03-09 14:58:32 -07:00
parent e86e1d88b2
commit 7858065113
117 changed files with 1735 additions and 1890 deletions

View File

@ -48,8 +48,8 @@ concurrency at this writing:
* [`std::task`] - All code relating to tasks and task scheduling,
* [`std::comm`] - The message passing interface,
* [`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::SyncSender`] - An extension of `pipes::stream` that provides synchronous message sending,
* [`sync::SyncReceiver`] - 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,
@ -70,8 +70,8 @@ concurrency at this writing:
[`std::task`]: std/task/index.html
[`std::comm`]: std/comm/index.html
[`sync::DuplexStream`]: sync/struct.DuplexStream.html
[`sync::SyncChan`]: sync/struct.SyncChan.html
[`sync::SyncPort`]: sync/struct.SyncPort.html
[`sync::SyncSender`]: sync/struct.SyncSender.html
[`sync::SyncReceiver`]: sync/struct.SyncReceiver.html
[`sync::rendezvous`]: sync/fn.rendezvous.html
[`sync::Arc`]: sync/struct.Arc.html
[`sync::RWArc`]: sync/struct.RWArc.html
@ -141,118 +141,115 @@ receiving messages. Pipes are low-level communication building-blocks and so
come in a variety of forms, each one appropriate for a different use case. In
what follows, we cover the most commonly used varieties.
The simplest way to create a pipe is to use `Chan::new`
function to create a `(Port, Chan)` pair. In Rust parlance, a *channel*
is a sending endpoint of a pipe, and a *port* is the receiving
The simplest way to create a pipe is to use the `channel`
function to create a `(Sender, Receiver)` pair. In Rust parlance, a *sender*
is a sending endpoint of a pipe, and a *receiver* is the receiving
endpoint. Consider the following example of calculating two results
concurrently:
~~~~
# use std::task::spawn;
let (port, chan): (Port<int>, Chan<int>) = Chan::new();
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
spawn(proc() {
let result = some_expensive_computation();
chan.send(result);
tx.send(result);
});
some_other_expensive_computation();
let result = port.recv();
let result = rx.recv();
# fn some_expensive_computation() -> int { 42 }
# fn some_other_expensive_computation() {}
~~~~
Let's examine this example in detail. First, the `let` statement creates a
stream for sending and receiving integers (the left-hand side of the `let`,
`(chan, port)`, is an example of a *destructuring let*: the pattern separates
`(tx, rx)`, is an example of a *destructuring let*: the pattern separates
a tuple into its component parts).
~~~~
let (port, chan): (Port<int>, Chan<int>) = Chan::new();
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
~~~~
The child task will use the channel to send data to the parent task,
which will wait to receive the data on the port. The next statement
The child task will use the sender to send data to the parent task,
which will wait to receive the data on the receiver. The next statement
spawns the child task.
~~~~
# use std::task::spawn;
# fn some_expensive_computation() -> int { 42 }
# let (port, chan) = Chan::new();
# let (tx, rx) = channel();
spawn(proc() {
let result = some_expensive_computation();
chan.send(result);
tx.send(result);
});
~~~~
Notice that the creation of the task closure transfers `chan` to the child
task implicitly: the closure captures `chan` in its environment. Both `Chan`
and `Port` are sendable types and may be captured into tasks or otherwise
Notice that the creation of the task closure transfers `tx` to the child
task implicitly: the closure captures `tx` in its environment. Both `Sender`
and `Receiver` are sendable types and may be captured into tasks or otherwise
transferred between them. In the example, the child task runs an expensive
computation, then sends the result over the captured channel.
Finally, the parent continues with some other expensive
computation, then waits for the child's result to arrive on the
port:
receiver:
~~~~
# fn some_other_expensive_computation() {}
# let (port, chan) = Chan::<int>::new();
# chan.send(0);
# let (tx, rx) = channel::<int>();
# tx.send(0);
some_other_expensive_computation();
let result = port.recv();
let result = rx.recv();
~~~~
The `Port` and `Chan` pair created by `Chan::new` enables efficient
The `Sender` and `Receiver` pair created by `channel` enables efficient
communication between a single sender and a single receiver, but multiple
senders cannot use a single `Chan`, and multiple receivers cannot use a single
`Port`. What if our example needed to compute multiple results across a number
of tasks? The following program is ill-typed:
senders cannot use a single `Sender` value, and multiple receivers cannot use a
single `Receiver` value. What if our example needed to compute multiple
results across a number of tasks? The following program is ill-typed:
~~~ {.ignore}
# use std::task::{spawn};
# fn some_expensive_computation() -> int { 42 }
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
chan.send(some_expensive_computation());
tx.send(some_expensive_computation());
});
// ERROR! The previous spawn statement already owns the channel,
// ERROR! The previous spawn statement already owns the sender,
// so the compiler will not allow it to be captured again
spawn(proc() {
chan.send(some_expensive_computation());
tx.send(some_expensive_computation());
});
~~~
Instead we can clone the `chan`, which allows for multiple senders.
Instead we can clone the `tx`, which allows for multiple senders.
~~~
# use std::task::spawn;
let (port, chan) = Chan::new();
let (tx, rx) = channel();
for init_val in range(0u, 3) {
// Create a new channel handle to distribute to the child task
let child_chan = chan.clone();
let child_tx = tx.clone();
spawn(proc() {
child_chan.send(some_expensive_computation(init_val));
child_tx.send(some_expensive_computation(init_val));
});
}
let result = port.recv() + port.recv() + port.recv();
let result = rx.recv() + rx.recv() + rx.recv();
# fn some_expensive_computation(_i: uint) -> int { 42 }
~~~
Cloning a `Chan` produces a new handle to the same channel, allowing multiple
tasks to send data to a single port. It also upgrades the channel internally in
Cloning a `Sender` produces a new handle to the same channel, allowing multiple
tasks to send data to a single receiver. It upgrades the channel internally in
order to allow this functionality, which means that channels that are not
cloned can avoid the overhead required to handle multiple senders. But this
fact has no bearing on the channel's usage: the upgrade is transparent.
Note that the above cloning example is somewhat contrived since
you could also simply use three `Chan` pairs, but it serves to
you could also simply use three `Sender` pairs, but it serves to
illustrate the point. For reference, written with multiple streams, it
might look like the example below.
@ -261,16 +258,16 @@ might look like the example below.
# use std::vec;
// Create a vector of ports, one for each child task
let ports = vec::from_fn(3, |init_val| {
let (port, chan) = Chan::new();
let rxs = vec::from_fn(3, |init_val| {
let (tx, rx) = channel();
spawn(proc() {
chan.send(some_expensive_computation(init_val));
tx.send(some_expensive_computation(init_val));
});
port
rx
});
// Wait on each port, accumulating the results
let result = ports.iter().fold(0, |accum, port| accum + port.recv() );
let result = rxs.iter().fold(0, |accum, rx| accum + rx.recv() );
# fn some_expensive_computation(_i: uint) -> int { 42 }
~~~
@ -281,7 +278,7 @@ later.
The basic example below illustrates this.
~~~
# extern crate sync;
extern crate sync;
# fn main() {
# fn make_a_sandwich() {};
@ -342,9 +339,10 @@ Here is a small example showing how to use Arcs. We wish to run concurrently sev
a single large vector of floats. Each task needs the full vector to perform its duty.
~~~
# extern crate sync;
extern crate rand;
# use std::vec;
extern crate rand;
extern crate sync;
use std::vec;
use sync::Arc;
fn pnorm(nums: &~[f64], p: uint) -> f64 {
@ -358,11 +356,11 @@ fn main() {
let numbers_arc = Arc::new(numbers);
for num in range(1u, 10) {
let (port, chan) = Chan::new();
chan.send(numbers_arc.clone());
let (tx, rx) = channel();
tx.send(numbers_arc.clone());
spawn(proc() {
let local_arc : Arc<~[f64]> = port.recv();
let local_arc : Arc<~[f64]> = rx.recv();
let task_numbers = local_arc.get();
println!("{}-norm = {}", num, pnorm(task_numbers, num));
});
@ -395,8 +393,8 @@ and a clone of it is sent to each task
# 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 (tx, rx) = channel();
tx.send(numbers_arc.clone());
# }
~~~
@ -412,9 +410,9 @@ Each task recovers the underlying data by
# 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 (tx, rx) = channel();
# tx.send(numbers_arc.clone());
# let local_arc : Arc<~[f64]> = rx.recv();
let task_numbers = local_arc.get();
# }
~~~
@ -486,19 +484,18 @@ 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 `sync::comm::DuplexStream()` supports this pattern. We'll
function `sync::comm::duplex` supports this pattern. We'll
look briefly at how to use it.
To see how `DuplexStream()` works, we will create a child task
To see how `duplex` works, we will create a child task
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:
~~~
# extern crate sync;
extern crate sync;
# fn main() {
# use sync::DuplexStream;
fn stringifier(channel: &DuplexStream<~str, uint>) {
fn stringifier(channel: &sync::DuplexStream<~str, uint>) {
let mut value: uint;
loop {
value = channel.recv();
@ -520,10 +517,10 @@ response itself is simply the stringified version of the received value,
Here is the code for the parent task:
~~~
# extern crate sync;
extern crate sync;
# use std::task::spawn;
# use sync::DuplexStream;
# fn stringifier(channel: &DuplexStream<~str, uint>) {
# fn stringifier(channel: &sync::DuplexStream<~str, uint>) {
# let mut value: uint;
# loop {
# value = channel.recv();
@ -533,7 +530,7 @@ Here is the code for the parent task:
# }
# fn main() {
let (from_child, to_child) = DuplexStream::new();
let (from_child, to_child) = sync::duplex();
spawn(proc() {
stringifier(&to_child);

View File

@ -96,7 +96,7 @@ syn keyword rustTrait MutableVector MutableTotalOrdVector
syn keyword rustTrait Vector VectorVector CloneableVector ImmutableVector
"syn keyword rustFunction stream
syn keyword rustTrait Port Chan
syn keyword rustTrait Sender Receiver
"syn keyword rustFunction spawn
syn keyword rustSelf self

View File

@ -237,7 +237,7 @@ pub struct Exec {
enum Work<'a, T> {
WorkValue(T),
WorkFromTask(&'a Prep<'a>, Port<(Exec, T)>),
WorkFromTask(&'a Prep<'a>, Receiver<(Exec, T)>),
}
fn json_encode<'a, T:Encodable<json::Encoder<'a>>>(t: &T) -> ~str {
@ -411,7 +411,7 @@ impl<'a> Prep<'a> {
_ => {
debug!("Cache miss!");
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let blk = bo.take_unwrap();
// FIXME: What happens if the task fails?
@ -421,9 +421,9 @@ impl<'a> Prep<'a> {
discovered_outputs: WorkMap::new(),
};
let v = blk(&mut exe);
chan.send((exe, v));
tx.send((exe, v));
});
Work::from_task(self, port)
Work::from_task(self, rx)
}
}
}
@ -437,7 +437,7 @@ impl<'a, T:Send +
pub fn from_value(elt: T) -> Work<'a, T> {
WorkValue(elt)
}
pub fn from_task(prep: &'a Prep<'a>, port: Port<(Exec, T)>)
pub fn from_task(prep: &'a Prep<'a>, port: Receiver<(Exec, T)>)
-> Work<'a, T> {
WorkFromTask(prep, port)
}

View File

@ -255,11 +255,11 @@ mod test {
#[test]
fn some_channels() {
run(proc() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
c.send(());
tx.send(());
});
p.recv();
rx.recv();
});
}
@ -272,11 +272,11 @@ mod test {
for _ in range(0, 20) {
pool.spawn(TaskOpts::new(), proc() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
c.send(());
tx.send(());
});
p.recv();
rx.recv();
});
}

View File

@ -258,15 +258,15 @@ pub fn run(main: proc()) -> int {
// Create a scheduler pool and spawn the main task into this pool. We will
// get notified over a channel when the main task exits.
let mut pool = SchedPool::new(PoolConfig::new());
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let mut opts = TaskOpts::new();
opts.notify_chan = Some(chan);
opts.notify_chan = Some(tx);
opts.name = Some("<main>".into_maybe_owned());
pool.spawn(opts, main);
// Wait for the main task to return, and set the process error code
// appropriately.
if port.recv().is_err() {
if rx.recv().is_err() {
os::set_exit_status(rt::DEFAULT_ERROR_CODE);
}
@ -309,7 +309,7 @@ pub struct SchedPool {
priv sleepers: SleeperList,
priv factory: fn() -> ~rtio::EventLoop,
priv task_state: TaskState,
priv tasks_done: Port<()>,
priv tasks_done: Receiver<()>,
}
/// This is an internal state shared among a pool of schedulers. This is used to
@ -318,7 +318,7 @@ pub struct SchedPool {
#[deriving(Clone)]
struct TaskState {
cnt: UnsafeArc<AtomicUint>,
done: Chan<()>,
done: Sender<()>,
}
impl SchedPool {
@ -471,11 +471,11 @@ impl SchedPool {
}
impl TaskState {
fn new() -> (Port<()>, TaskState) {
let (p, c) = Chan::new();
(p, TaskState {
fn new() -> (Receiver<()>, TaskState) {
let (tx, rx) = channel();
(rx, TaskState {
cnt: UnsafeArc::new(AtomicUint::new(0)),
done: c,
done: tx,
})
}

View File

@ -1091,25 +1091,25 @@ mod test {
fn test_home_sched() {
let mut pool = pool();
let (dport, dchan) = Chan::new();
let (dtx, drx) = channel();
{
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let mut handle1 = pool.spawn_sched();
let mut handle2 = pool.spawn_sched();
handle1.send(TaskFromFriend(pool.task(TaskOpts::new(), proc() {
chan.send(sched_id());
tx.send(sched_id());
})));
let sched1_id = port.recv();
let sched1_id = rx.recv();
let mut task = pool.task(TaskOpts::new(), proc() {
assert_eq!(sched_id(), sched1_id);
dchan.send(());
dtx.send(());
});
task.give_home(HomeSched(handle1));
handle2.send(TaskFromFriend(task));
}
dport.recv();
drx.recv();
pool.shutdown();
}
@ -1210,7 +1210,7 @@ mod test {
});
// Signal from the special task that we are done.
let (port, chan) = Chan::<()>::new();
let (tx, rx) = channel::<()>();
fn run(next: ~GreenTask) {
let mut task = GreenTask::convert(Local::take());
@ -1221,7 +1221,7 @@ mod test {
let normal_task = GreenTask::new(&mut normal_sched.stack_pool, None, proc() {
run(task2);
run(task4);
port.recv();
rx.recv();
let mut nh = normal_handle;
nh.send(Shutdown);
let mut sh = special_handle;
@ -1232,7 +1232,7 @@ mod test {
let special_task = GreenTask::new(&mut special_sched.stack_pool, None, proc() {
run(task1);
run(task3);
chan.send(());
tx.send(());
});
special_sched.enqueue_task(special_task);
@ -1280,24 +1280,24 @@ mod test {
#[test]
fn wakeup_across_scheds() {
let (port1, chan1) = Chan::new();
let (port2, chan2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
let mut pool1 = pool();
let mut pool2 = pool();
pool1.spawn(TaskOpts::new(), proc() {
let id = sched_id();
chan1.send(());
port2.recv();
tx1.send(());
rx2.recv();
assert_eq!(id, sched_id());
});
pool2.spawn(TaskOpts::new(), proc() {
let id = sched_id();
port1.recv();
rx1.recv();
assert_eq!(id, sched_id());
chan2.send(());
tx2.send(());
});
pool1.shutdown();
@ -1319,18 +1319,18 @@ mod test {
#[test]
fn multithreading() {
run(proc() {
let mut ports = ~[];
let mut rxs = ~[];
for _ in range(0, 10) {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
chan.send(());
tx.send(());
});
ports.push(port);
rxs.push(rx);
}
loop {
match ports.pop() {
Some(port) => port.recv(),
match rxs.pop() {
Some(rx) => rx.recv(),
None => break,
}
}
@ -1340,45 +1340,45 @@ mod test {
#[test]
fn thread_ring() {
run(proc() {
let (end_port, end_chan) = Chan::new();
let (end_tx, end_rx) = channel();
let n_tasks = 10;
let token = 2000;
let (mut p, ch1) = Chan::new();
ch1.send((token, end_chan));
let (tx1, mut rx) = channel();
tx1.send((token, end_tx));
let mut i = 2;
while i <= n_tasks {
let (next_p, ch) = Chan::new();
let (tx, next_rx) = channel();
let imm_i = i;
let imm_p = p;
let imm_rx = rx;
spawn(proc() {
roundtrip(imm_i, n_tasks, &imm_p, &ch);
roundtrip(imm_i, n_tasks, &imm_rx, &tx);
});
p = next_p;
rx = next_rx;
i += 1;
}
let p = p;
let rx = rx;
spawn(proc() {
roundtrip(1, n_tasks, &p, &ch1);
roundtrip(1, n_tasks, &rx, &tx1);
});
end_port.recv();
end_rx.recv();
});
fn roundtrip(id: int, n_tasks: int,
p: &Port<(int, Chan<()>)>,
ch: &Chan<(int, Chan<()>)>) {
rx: &Receiver<(int, Sender<()>)>,
tx: &Sender<(int, Sender<()>)>) {
loop {
match p.recv() {
(1, end_chan) => {
match rx.recv() {
(1, end_tx) => {
debug!("{}\n", id);
end_chan.send(());
end_tx.send(());
return;
}
(token, end_chan) => {
(token, end_tx) => {
debug!("thread: {} got token: {}", id, token);
ch.send((token - 1, end_chan));
tx.send((token - 1, end_tx));
if token <= n_tasks {
return;
}
@ -1416,15 +1416,15 @@ mod test {
event_loop_factory: Some(basic::event_loop),
});
pool.spawn(TaskOpts::new(), proc() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
// This task should not be able to starve the sender;
// The sender should get stolen to another thread.
spawn(proc() {
while port.try_recv() != comm::Data(()) { }
while rx.try_recv() != comm::Data(()) { }
});
chan.send(());
tx.send(());
});
pool.shutdown();
}
@ -1432,18 +1432,18 @@ mod test {
#[test]
fn dont_starve_2() {
run(proc() {
let (port, chan) = Chan::new();
let (_port2, chan2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, _rx2) = channel();
// This task should not be able to starve the other task.
// The sends should eventually yield.
spawn(proc() {
while port.try_recv() != comm::Data(()) {
chan2.send(());
while rx1.try_recv() != comm::Data(()) {
tx2.send(());
}
});
chan.send(());
tx1.send(());
});
}
@ -1466,29 +1466,29 @@ mod test {
// without affecting other schedulers
for _ in range(0, 20) {
let mut pool = pool();
let (start_po, start_ch) = Chan::new();
let (fin_po, fin_ch) = Chan::new();
let (start_tx, start_rx) = channel();
let (fin_tx, fin_rx) = channel();
let mut handle = pool.spawn_sched();
handle.send(PinnedTask(pool.task(TaskOpts::new(), proc() {
unsafe {
let mut guard = LOCK.lock();
start_ch.send(());
start_tx.send(());
guard.wait(); // block the scheduler thread
guard.signal(); // let them know we have the lock
}
fin_ch.send(());
fin_tx.send(());
})));
drop(handle);
let mut handle = pool.spawn_sched();
handle.send(PinnedTask(pool.task(TaskOpts::new(), proc() {
// Wait until the other task has its lock
start_po.recv();
start_rx.recv();
fn pingpong(po: &Port<int>, ch: &Chan<int>) {
fn pingpong(po: &Receiver<int>, ch: &Sender<int>) {
let mut val = 20;
while val > 0 {
val = po.recv();
@ -1496,17 +1496,17 @@ mod test {
}
}
let (setup_po, setup_ch) = Chan::new();
let (parent_po, parent_ch) = Chan::new();
let (setup_tx, setup_rx) = channel();
let (parent_tx, parent_rx) = channel();
spawn(proc() {
let (child_po, child_ch) = Chan::new();
setup_ch.send(child_ch);
pingpong(&child_po, &parent_ch);
let (child_tx, child_rx) = channel();
setup_tx.send(child_tx);
pingpong(&child_rx, &parent_tx);
});
let child_ch = setup_po.recv();
child_ch.send(20);
pingpong(&parent_po, &child_ch);
let child_tx = setup_rx.recv();
child_tx.send(20);
pingpong(&parent_rx, &child_tx);
unsafe {
let mut guard = LOCK.lock();
guard.signal(); // wakeup waiting scheduler
@ -1515,7 +1515,7 @@ mod test {
})));
drop(handle);
fin_po.recv();
fin_rx.recv();
pool.shutdown();
}
unsafe { LOCK.destroy(); }

View File

@ -500,21 +500,21 @@ mod tests {
#[test]
fn smoke() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn_opts(TaskOpts::new(), proc() {
c.send(());
tx.send(());
});
p.recv();
rx.recv();
}
#[test]
fn smoke_fail() {
let (p, c) = Chan::<()>::new();
let (tx, rx) = channel::<int>();
spawn_opts(TaskOpts::new(), proc() {
let _c = c;
let _tx = tx;
fail!()
});
assert_eq!(p.recv_opt(), None);
assert_eq!(rx.recv_opt(), None);
}
#[test]
@ -522,55 +522,54 @@ mod tests {
let mut opts = TaskOpts::new();
opts.name = Some("test".into_maybe_owned());
opts.stack_size = Some(20 * 4096);
let (p, c) = Chan::new();
opts.notify_chan = Some(c);
let (tx, rx) = channel();
opts.notify_chan = Some(tx);
spawn_opts(opts, proc() {});
assert!(p.recv().is_ok());
assert!(rx.recv().is_ok());
}
#[test]
fn smoke_opts_fail() {
let mut opts = TaskOpts::new();
let (p, c) = Chan::new();
opts.notify_chan = Some(c);
let (tx, rx) = channel();
opts.notify_chan = Some(tx);
spawn_opts(opts, proc() { fail!() });
assert!(p.recv().is_err());
assert!(rx.recv().is_err());
}
#[test]
fn yield_test() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn_opts(TaskOpts::new(), proc() {
for _ in range(0, 10) { task::deschedule(); }
c.send(());
tx.send(());
});
p.recv();
rx.recv();
}
#[test]
fn spawn_children() {
let (p, c) = Chan::new();
let (tx1, rx) = channel();
spawn_opts(TaskOpts::new(), proc() {
let (p, c2) = Chan::new();
let (tx2, rx) = channel();
spawn(proc() {
let (p, c3) = Chan::new();
let (tx3, rx) = channel();
spawn(proc() {
c3.send(());
tx3.send(());
});
p.recv();
c2.send(());
rx.recv();
tx2.send(());
});
p.recv();
c.send(());
rx.recv();
tx1.send(());
});
p.recv();
rx.recv();
}
#[test]
fn spawn_inherits() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn_opts(TaskOpts::new(), proc() {
let c = c;
spawn(proc() {
let mut task: ~Task = Local::take();
match task.maybe_take_runtime::<GreenTask>() {
@ -580,9 +579,9 @@ mod tests {
None => fail!(),
}
Local::put(task);
c.send(());
tx.send(());
});
});
p.recv();
rx.recv();
}
}

View File

@ -532,26 +532,24 @@ mod tests {
fn test_file_desc() {
// Run this test with some pipes so we don't have to mess around with
// opening or closing files.
unsafe {
let os::Pipe { input, out } = os::pipe();
let mut reader = FileDesc::new(input, true);
let mut writer = FileDesc::new(out, true);
let os::Pipe { input, out } = os::pipe();
let mut reader = FileDesc::new(input, true);
let mut writer = FileDesc::new(out, true);
writer.inner_write(bytes!("test")).unwrap();
let mut buf = [0u8, ..4];
match reader.inner_read(buf) {
Ok(4) => {
assert_eq!(buf[0], 't' as u8);
assert_eq!(buf[1], 'e' as u8);
assert_eq!(buf[2], 's' as u8);
assert_eq!(buf[3], 't' as u8);
}
r => fail!("invalid read: {:?}", r)
writer.inner_write(bytes!("test")).unwrap();
let mut buf = [0u8, ..4];
match reader.inner_read(buf) {
Ok(4) => {
assert_eq!(buf[0], 't' as u8);
assert_eq!(buf[1], 'e' as u8);
assert_eq!(buf[2], 's' as u8);
assert_eq!(buf[3], 't' as u8);
}
assert!(writer.inner_read(buf).is_err());
assert!(reader.inner_write(buf).is_err());
r => fail!("invalid read: {:?}", r)
}
assert!(writer.inner_read(buf).is_err());
assert!(reader.inner_write(buf).is_err());
}
#[test]

View File

@ -336,7 +336,7 @@ impl rtio::IoFactory for IoFactory {
})
}
}
fn signal(&mut self, _signal: Signum, _channel: Chan<Signum>)
fn signal(&mut self, _signal: Signum, _channel: Sender<Signum>)
-> IoResult<~RtioSignal> {
Err(unimpl())
}

View File

@ -33,28 +33,28 @@ use task;
// only torn down after everything else has exited. This means that these
// variables are read-only during use (after initialization) and both of which
// are safe to use concurrently.
static mut HELPER_CHAN: *mut Chan<Req> = 0 as *mut Chan<Req>;
static mut HELPER_CHAN: *mut Sender<Req> = 0 as *mut Sender<Req>;
static mut HELPER_SIGNAL: imp::signal = 0 as imp::signal;
static mut TIMER_HELPER_EXIT: StaticNativeMutex = NATIVE_MUTEX_INIT;
pub fn boot(helper: fn(imp::signal, Port<Req>)) {
pub fn boot(helper: fn(imp::signal, Receiver<Req>)) {
static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
static mut INITIALIZED: bool = false;
unsafe {
let mut _guard = LOCK.lock();
if !INITIALIZED {
let (msgp, msgc) = Chan::new();
let (tx, rx) = channel();
// promote this to a shared channel
drop(msgc.clone());
HELPER_CHAN = cast::transmute(~msgc);
drop(tx.clone());
HELPER_CHAN = cast::transmute(~tx);
let (receive, send) = imp::new();
HELPER_SIGNAL = send;
task::spawn(proc() {
bookkeeping::decrement();
helper(receive, msgp);
helper(receive, rx);
TIMER_HELPER_EXIT.lock().signal()
});
@ -86,8 +86,8 @@ fn shutdown() {
// Clean up after ther helper thread
unsafe {
imp::close(HELPER_SIGNAL);
let _chan: ~Chan<Req> = cast::transmute(HELPER_CHAN);
HELPER_CHAN = 0 as *mut Chan<Req>;
let _chan: ~Sender<Req> = cast::transmute(HELPER_CHAN);
HELPER_CHAN = 0 as *mut Sender<Req>;
HELPER_SIGNAL = 0 as imp::signal;
}
}

View File

@ -64,7 +64,7 @@ pub struct Timer {
}
struct Inner {
chan: Option<Chan<()>>,
tx: Option<Sender<()>>,
interval: u64,
repeat: bool,
target: u64,
@ -78,7 +78,7 @@ pub enum Req {
// Remove a timer based on its id and then send it back on the channel
// provided
RemoveTimer(uint, Chan<~Inner>),
RemoveTimer(uint, Sender<~Inner>),
// Shut down the loop and then ACK this channel once it's shut down
Shutdown,
@ -93,7 +93,7 @@ fn now() -> u64 {
}
}
fn helper(input: libc::c_int, messages: Port<Req>) {
fn helper(input: libc::c_int, messages: Receiver<Req>) {
let mut set: imp::fd_set = unsafe { mem::init() };
let mut fd = FileDesc::new(input, true);
@ -118,13 +118,13 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
let mut timer = match active.shift() {
Some(timer) => timer, None => return
};
let chan = timer.chan.take_unwrap();
if chan.try_send(()) && timer.repeat {
timer.chan = Some(chan);
let tx = timer.tx.take_unwrap();
if tx.try_send(()) && timer.repeat {
timer.tx = Some(tx);
timer.target += timer.interval;
insert(timer, active);
} else {
drop(chan);
drop(tx);
dead.push((timer.id, timer));
}
}
@ -208,7 +208,7 @@ impl Timer {
Ok(Timer {
id: id,
inner: Some(~Inner {
chan: None,
tx: None,
interval: 0,
target: 0,
repeat: false,
@ -233,9 +233,9 @@ impl Timer {
match self.inner.take() {
Some(i) => i,
None => {
let (p, c) = Chan::new();
timer_helper::send(RemoveTimer(self.id, c));
p.recv()
let (tx, rx) = channel();
timer_helper::send(RemoveTimer(self.id, tx));
rx.recv()
}
}
}
@ -244,38 +244,38 @@ impl Timer {
impl rtio::RtioTimer for Timer {
fn sleep(&mut self, msecs: u64) {
let mut inner = self.inner();
inner.chan = None; // cancel any previous request
inner.tx = None; // cancel any previous request
self.inner = Some(inner);
Timer::sleep(msecs);
}
fn oneshot(&mut self, msecs: u64) -> Port<()> {
fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
let now = now();
let mut inner = self.inner();
let (p, c) = Chan::new();
let (tx, rx) = channel();
inner.repeat = false;
inner.chan = Some(c);
inner.tx = Some(tx);
inner.interval = msecs;
inner.target = now + msecs;
timer_helper::send(NewTimer(inner));
return p;
return rx;
}
fn period(&mut self, msecs: u64) -> Port<()> {
fn period(&mut self, msecs: u64) -> Receiver<()> {
let now = now();
let mut inner = self.inner();
let (p, c) = Chan::new();
let (tx, rx) = channel();
inner.repeat = true;
inner.chan = Some(c);
inner.tx = Some(tx);
inner.interval = msecs;
inner.target = now + msecs;
timer_helper::send(NewTimer(inner));
return p;
return rx;
}
}

View File

@ -46,12 +46,12 @@ pub struct Timer {
#[allow(visible_private_types)]
pub enum Req {
NewTimer(libc::c_int, Chan<()>, bool, imp::itimerspec),
RemoveTimer(libc::c_int, Chan<()>),
NewTimer(libc::c_int, Sender<()>, bool, imp::itimerspec),
RemoveTimer(libc::c_int, Sender<()>),
Shutdown,
}
fn helper(input: libc::c_int, messages: Port<Req>) {
fn helper(input: libc::c_int, messages: Receiver<Req>) {
let efd = unsafe { imp::epoll_create(10) };
let _fd1 = FileDesc::new(input, true);
let _fd2 = FileDesc::new(efd, true);
@ -76,7 +76,7 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
add(efd, input);
let events: [imp::epoll_event, ..16] = unsafe { mem::init() };
let mut list: ~[(libc::c_int, Chan<()>, bool)] = ~[];
let mut list: ~[(libc::c_int, Sender<()>, bool)] = ~[];
'outer: loop {
let n = match unsafe {
imp::epoll_wait(efd, events.as_ptr(),
@ -197,9 +197,9 @@ impl Timer {
fn remove(&mut self) {
if !self.on_worker { return }
let (p, c) = Chan::new();
timer_helper::send(RemoveTimer(self.fd.fd(), c));
p.recv();
let (tx, rx) = channel();
timer_helper::send(RemoveTimer(self.fd.fd(), tx));
rx.recv();
self.on_worker = false;
}
}
@ -224,8 +224,8 @@ impl rtio::RtioTimer for Timer {
// before returning to guarantee the invariant that when oneshot() and
// period() return that the old port will never receive any more messages.
fn oneshot(&mut self, msecs: u64) -> Port<()> {
let (p, c) = Chan::new();
fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
let (tx, rx) = channel();
let new_value = imp::itimerspec {
it_interval: imp::timespec { tv_sec: 0, tv_nsec: 0 },
@ -234,26 +234,26 @@ impl rtio::RtioTimer for Timer {
tv_nsec: ((msecs % 1000) * 1000000) as libc::c_long,
}
};
timer_helper::send(NewTimer(self.fd.fd(), c, true, new_value));
p.recv();
timer_helper::send(NewTimer(self.fd.fd(), tx, true, new_value));
rx.recv();
self.on_worker = true;
return p;
return rx;
}
fn period(&mut self, msecs: u64) -> Port<()> {
let (p, c) = Chan::new();
fn period(&mut self, msecs: u64) -> Receiver<()> {
let (tx, rx) = channel();
let spec = imp::timespec {
tv_sec: (msecs / 1000) as libc::time_t,
tv_nsec: ((msecs % 1000) * 1000000) as libc::c_long,
};
let new_value = imp::itimerspec { it_interval: spec, it_value: spec, };
timer_helper::send(NewTimer(self.fd.fd(), c, false, new_value));
p.recv();
timer_helper::send(NewTimer(self.fd.fd(), tx, false, new_value));
rx.recv();
self.on_worker = true;
return p;
return rx;
}
}

View File

@ -34,12 +34,12 @@ pub struct Timer {
}
pub enum Req {
NewTimer(libc::HANDLE, Chan<()>, bool),
RemoveTimer(libc::HANDLE, Chan<()>),
NewTimer(libc::HANDLE, Sender<()>, bool),
RemoveTimer(libc::HANDLE, Sender<()>),
Shutdown,
}
fn helper(input: libc::HANDLE, messages: Port<Req>) {
fn helper(input: libc::HANDLE, messages: Receiver<Req>) {
let mut objs = ~[input];
let mut chans = ~[];
@ -113,9 +113,9 @@ impl Timer {
fn remove(&mut self) {
if !self.on_worker { return }
let (p, c) = Chan::new();
timer_helper::send(RemoveTimer(self.obj, c));
p.recv();
let (tx, rx) = channel();
timer_helper::send(RemoveTimer(self.obj, tx));
rx.recv();
self.on_worker = false;
}
@ -136,9 +136,9 @@ impl rtio::RtioTimer for Timer {
let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) };
}
fn oneshot(&mut self, msecs: u64) -> Port<()> {
fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
self.remove();
let (p, c) = Chan::new();
let (tx, rx) = channel();
// see above for the calculation
let due = -(msecs * 10000) as libc::LARGE_INTEGER;
@ -147,14 +147,14 @@ impl rtio::RtioTimer for Timer {
ptr::mut_null(), 0)
}, 1);
timer_helper::send(NewTimer(self.obj, c, true));
timer_helper::send(NewTimer(self.obj, tx, true));
self.on_worker = true;
return p;
return rx;
}
fn period(&mut self, msecs: u64) -> Port<()> {
fn period(&mut self, msecs: u64) -> Receiver<()> {
self.remove();
let (p, c) = Chan::new();
let (tx, rx) = channel();
// see above for the calculation
let due = -(msecs * 10000) as libc::LARGE_INTEGER;
@ -163,10 +163,10 @@ impl rtio::RtioTimer for Timer {
ptr::null(), ptr::mut_null(), 0)
}, 1);
timer_helper::send(NewTimer(self.obj, c, false));
timer_helper::send(NewTimer(self.obj, tx, false));
self.on_worker = true;
return p;
return rx;
}
}

View File

@ -262,21 +262,21 @@ mod tests {
#[test]
fn smoke() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
c.send(());
tx.send(());
});
p.recv();
rx.recv();
}
#[test]
fn smoke_fail() {
let (p, c) = Chan::<()>::new();
let (tx, rx) = channel::<()>();
spawn(proc() {
let _c = c;
let _tx = tx;
fail!()
});
assert_eq!(p.recv_opt(), None);
assert_eq!(rx.recv_opt(), None);
}
#[test]
@ -284,55 +284,54 @@ mod tests {
let mut opts = TaskOpts::new();
opts.name = Some("test".into_maybe_owned());
opts.stack_size = Some(20 * 4096);
let (p, c) = Chan::new();
opts.notify_chan = Some(c);
let (tx, rx) = channel();
opts.notify_chan = Some(tx);
spawn_opts(opts, proc() {});
assert!(p.recv().is_ok());
assert!(rx.recv().is_ok());
}
#[test]
fn smoke_opts_fail() {
let mut opts = TaskOpts::new();
let (p, c) = Chan::new();
opts.notify_chan = Some(c);
let (tx, rx) = channel();
opts.notify_chan = Some(tx);
spawn_opts(opts, proc() { fail!() });
assert!(p.recv().is_err());
assert!(rx.recv().is_err());
}
#[test]
fn yield_test() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
for _ in range(0, 10) { task::deschedule(); }
c.send(());
tx.send(());
});
p.recv();
rx.recv();
}
#[test]
fn spawn_children() {
let (p, c) = Chan::new();
let (tx1, rx) = channel();
spawn(proc() {
let (p, c2) = Chan::new();
let (tx2, rx) = channel();
spawn(proc() {
let (p, c3) = Chan::new();
let (tx3, rx) = channel();
spawn(proc() {
c3.send(());
tx3.send(());
});
p.recv();
c2.send(());
rx.recv();
tx2.send(());
});
p.recv();
c.send(());
rx.recv();
tx1.send(());
});
p.recv();
rx.recv();
}
#[test]
fn spawn_inherits() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let c = c;
spawn(proc() {
let mut task: ~Task = Local::take();
match task.maybe_take_runtime::<Ops>() {
@ -342,9 +341,9 @@ mod tests {
None => fail!(),
}
Local::put(task);
c.send(());
tx.send(());
});
});
p.recv();
rx.recv();
}
}

View File

@ -149,13 +149,13 @@ mod test {
#[test]
fn test_os_rng_tasks() {
let mut chans = ~[];
let mut txs = ~[];
for _ in range(0, 20) {
let (p, c) = Chan::new();
chans.push(c);
let (tx, rx) = channel();
txs.push(tx);
task::spawn(proc() {
// wait until all the tasks are ready to go.
p.recv();
rx.recv();
// deschedule to attempt to interleave things as much
// as possible (XXX: is this a good test?)
@ -175,8 +175,8 @@ mod test {
}
// start all the tasks
for c in chans.iter() {
c.send(())
for tx in txs.iter() {
tx.send(())
}
}
}

View File

@ -379,9 +379,9 @@ pub fn monitor(f: proc()) {
task_builder.opts.stack_size = Some(STACK_SIZE);
}
let (p, c) = Chan::new();
let w = io::ChanWriter::new(c);
let mut r = io::PortReader::new(p);
let (tx, rx) = channel();
let w = io::ChanWriter::new(tx);
let mut r = io::ChanReader::new(rx);
match task_builder.try(proc() {
io::stdio::set_stderr(~w as ~io::Writer);

View File

@ -116,12 +116,12 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
//
// The basic idea is to not use a default_handler() for rustc, and then also
// not print things by default to the actual stderr.
let (p, c) = Chan::new();
let w1 = io::ChanWriter::new(c);
let (tx, rx) = channel();
let w1 = io::ChanWriter::new(tx);
let w2 = w1.clone();
let old = io::stdio::set_stderr(~w1);
spawn(proc() {
let mut p = io::PortReader::new(p);
let mut p = io::ChanReader::new(rx);
let mut err = old.unwrap_or(~io::stderr() as ~Writer);
io::util::copy(&mut p, &mut err).unwrap();
});

View File

@ -135,7 +135,7 @@ mod test_remote {
// actually trigger what they say they will.
#[test]
fn smoke_test() {
struct MyCallback(Option<Chan<int>>);
struct MyCallback(Option<Sender<int>>);
impl Callback for MyCallback {
fn call(&mut self) {
// this can get called more than once, but we only want to send
@ -147,8 +147,8 @@ mod test_remote {
}
}
let (port, chan) = Chan::new();
let cb = ~MyCallback(Some(chan));
let (tx, rx) = channel();
let cb = ~MyCallback(Some(tx));
let watcher = AsyncWatcher::new(&mut local_loop().loop_,
cb as ~Callback);
@ -157,7 +157,7 @@ mod test_remote {
watcher.fire();
});
assert_eq!(port.recv(), 1);
assert_eq!(rx.recv(), 1);
thread.join();
}
}

View File

@ -164,7 +164,7 @@ mod test {
// thread, close itself, and then come back to the last thread.
#[test]
fn test_homing_closes_correctly() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let mut pool = SchedPool::new(PoolConfig {
threads: 1,
event_loop_factory: None,
@ -172,11 +172,11 @@ mod test {
pool.spawn(TaskOpts::new(), proc() {
let listener = UdpWatcher::bind(local_loop(), next_test_ip4());
chan.send(listener.unwrap());
tx.send(listener.unwrap());
});
let task = pool.task(TaskOpts::new(), proc() {
drop(port.recv());
drop(rx.recv());
});
pool.spawn_sched().send(sched::TaskFromFriend(task));
@ -185,7 +185,7 @@ mod test {
#[test]
fn test_homing_read() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let mut pool = SchedPool::new(PoolConfig {
threads: 1,
event_loop_factory: None,
@ -195,13 +195,13 @@ mod test {
let addr1 = next_test_ip4();
let addr2 = next_test_ip4();
let listener = UdpWatcher::bind(local_loop(), addr2);
chan.send((listener.unwrap(), addr1));
tx.send((listener.unwrap(), addr1));
let mut listener = UdpWatcher::bind(local_loop(), addr1).unwrap();
listener.sendto([1, 2, 3, 4], addr2).unwrap();
});
let task = pool.task(TaskOpts::new(), proc() {
let (mut watcher, addr) = port.recv();
let (mut watcher, addr) = rx.recv();
let mut buf = [0, ..10];
assert_eq!(watcher.recvfrom(buf).unwrap(), (4, addr));
});

View File

@ -167,8 +167,8 @@ pub struct TcpListener {
home: HomeHandle,
handle: *uvll::uv_pipe_t,
priv closing_task: Option<BlockedTask>,
priv outgoing: Chan<Result<~rtio::RtioTcpStream, IoError>>,
priv incoming: Port<Result<~rtio::RtioTcpStream, IoError>>,
priv outgoing: Sender<Result<~rtio::RtioTcpStream, IoError>>,
priv incoming: Receiver<Result<~rtio::RtioTcpStream, IoError>>,
}
pub struct TcpAcceptor {
@ -329,13 +329,13 @@ impl TcpListener {
assert_eq!(unsafe {
uvll::uv_tcp_init(io.uv_loop(), handle)
}, 0);
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let l = ~TcpListener {
home: io.make_handle(),
handle: handle,
closing_task: None,
outgoing: chan,
incoming: port,
outgoing: tx,
incoming: rx,
};
let (addr, _len) = addr_to_sockaddr(address);
let res = unsafe {
@ -741,7 +741,7 @@ mod test {
#[test]
fn listen_ip4() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let addr = next_test_ip4();
spawn(proc() {
@ -751,7 +751,7 @@ mod test {
let mut w = match w.listen() {
Ok(w) => w, Err(e) => fail!("{:?}", e),
};
chan.send(());
tx.send(());
match w.accept() {
Ok(mut stream) => {
let mut buf = [0u8, ..10];
@ -766,7 +766,7 @@ mod test {
}
});
port.recv();
rx.recv();
let mut w = match TcpWatcher::connect(local_loop(), addr) {
Ok(w) => w, Err(e) => fail!("{:?}", e)
};
@ -777,7 +777,7 @@ mod test {
#[test]
fn listen_ip6() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let addr = next_test_ip6();
spawn(proc() {
@ -787,7 +787,7 @@ mod test {
let mut w = match w.listen() {
Ok(w) => w, Err(e) => fail!("{:?}", e),
};
chan.send(());
tx.send(());
match w.accept() {
Ok(mut stream) => {
let mut buf = [0u8, ..10];
@ -802,7 +802,7 @@ mod test {
}
});
port.recv();
rx.recv();
let mut w = match TcpWatcher::connect(local_loop(), addr) {
Ok(w) => w, Err(e) => fail!("{:?}", e)
};
@ -813,14 +813,14 @@ mod test {
#[test]
fn udp_recv_ip4() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let client = next_test_ip4();
let server = next_test_ip4();
spawn(proc() {
match UdpWatcher::bind(local_loop(), server) {
Ok(mut w) => {
chan.send(());
tx.send(());
let mut buf = [0u8, ..10];
match w.recvfrom(buf) {
Ok((10, addr)) => assert_eq!(addr, client),
@ -834,7 +834,7 @@ mod test {
}
});
port.recv();
rx.recv();
let mut w = match UdpWatcher::bind(local_loop(), client) {
Ok(w) => w, Err(e) => fail!("{:?}", e)
};
@ -845,14 +845,14 @@ mod test {
#[test]
fn udp_recv_ip6() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let client = next_test_ip6();
let server = next_test_ip6();
spawn(proc() {
match UdpWatcher::bind(local_loop(), server) {
Ok(mut w) => {
chan.send(());
tx.send(());
let mut buf = [0u8, ..10];
match w.recvfrom(buf) {
Ok((10, addr)) => assert_eq!(addr, client),
@ -866,7 +866,7 @@ mod test {
}
});
port.recv();
rx.recv();
let mut w = match UdpWatcher::bind(local_loop(), client) {
Ok(w) => w, Err(e) => fail!("{:?}", e)
};
@ -879,12 +879,12 @@ mod test {
fn test_read_read_read() {
let addr = next_test_ip4();
static MAX: uint = 5000;
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let listener = TcpListener::bind(local_loop(), addr).unwrap();
let mut acceptor = listener.listen().unwrap();
chan.send(());
tx.send(());
let mut stream = acceptor.accept().unwrap();
let buf = [1, .. 2048];
let mut total_bytes_written = 0;
@ -895,7 +895,7 @@ mod test {
}
});
port.recv();
rx.recv();
let mut stream = TcpWatcher::connect(local_loop(), addr).unwrap();
let mut buf = [0, .. 2048];
let mut total_bytes_read = 0;
@ -914,17 +914,17 @@ mod test {
fn test_udp_twice() {
let server_addr = next_test_ip4();
let client_addr = next_test_ip4();
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let mut client = UdpWatcher::bind(local_loop(), client_addr).unwrap();
port.recv();
rx.recv();
assert!(client.sendto([1], server_addr).is_ok());
assert!(client.sendto([2], server_addr).is_ok());
});
let mut server = UdpWatcher::bind(local_loop(), server_addr).unwrap();
chan.send(());
tx.send(());
let mut buf1 = [0];
let mut buf2 = [0];
let (nread1, src1) = server.recvfrom(buf1).unwrap();
@ -945,16 +945,16 @@ mod test {
let client_in_addr = next_test_ip4();
static MAX: uint = 500_000;
let (p1, c1) = Chan::new();
let (p2, c2) = Chan::new();
let (tx1, rx1) = channel::<()>();
let (tx2, rx2) = channel::<()>();
spawn(proc() {
let l = local_loop();
let mut server_out = UdpWatcher::bind(l, server_out_addr).unwrap();
let mut server_in = UdpWatcher::bind(l, server_in_addr).unwrap();
let (port, chan) = (p1, c2);
chan.send(());
port.recv();
let (tx, rx) = (tx2, rx1);
tx.send(());
rx.recv();
let msg = [1, .. 2048];
let mut total_bytes_sent = 0;
let mut buf = [1];
@ -975,9 +975,9 @@ mod test {
let l = local_loop();
let mut client_out = UdpWatcher::bind(l, client_out_addr).unwrap();
let mut client_in = UdpWatcher::bind(l, client_in_addr).unwrap();
let (port, chan) = (p2, c1);
port.recv();
chan.send(());
let (tx, rx) = (tx1, rx2);
rx.recv();
tx.send(());
let mut total_bytes_recv = 0;
let mut buf = [0, .. 2048];
while total_bytes_recv < MAX {
@ -1000,23 +1000,23 @@ mod test {
#[test]
fn test_read_and_block() {
let addr = next_test_ip4();
let (port, chan) = Chan::<Port<()>>::new();
let (tx, rx) = channel::<Receiver<()>>();
spawn(proc() {
let port2 = port.recv();
let rx = rx.recv();
let mut stream = TcpWatcher::connect(local_loop(), addr).unwrap();
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
port2.recv();
rx.recv();
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
port2.recv();
rx.recv();
});
let listener = TcpListener::bind(local_loop(), addr).unwrap();
let mut acceptor = listener.listen().unwrap();
let (port2, chan2) = Chan::new();
chan.send(port2);
let (tx2, rx2) = channel();
tx.send(rx2);
let mut stream = acceptor.accept().unwrap();
let mut buf = [0, .. 2048];
@ -1033,7 +1033,7 @@ mod test {
}
reads += 1;
chan2.try_send(());
tx2.try_send(());
}
// Make sure we had multiple reads
@ -1073,16 +1073,16 @@ mod test {
#[should_fail] #[test]
fn tcp_stream_fail_cleanup() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let addr = next_test_ip4();
spawn(proc() {
let w = TcpListener::bind(local_loop(), addr).unwrap();
let mut w = w.listen().unwrap();
chan.send(());
tx.send(());
drop(w.accept().unwrap());
});
port.recv();
rx.recv();
let _w = TcpWatcher::connect(local_loop(), addr).unwrap();
fail!();
}
@ -1097,17 +1097,17 @@ mod test {
#[should_fail] #[test]
fn udp_fail_other_task() {
let addr = next_test_ip4();
let (port, chan) = Chan::new();
let (tx, rx) = channel();
// force the handle to be created on a different scheduler, failure in
// the original task will force a homing operation back to this
// scheduler.
spawn(proc() {
let w = UdpWatcher::bind(local_loop(), addr).unwrap();
chan.send(w);
tx.send(w);
});
let _w = port.recv();
let _w = rx.recv();
fail!();
}
}

View File

@ -37,8 +37,8 @@ pub struct PipeWatcher {
pub struct PipeListener {
home: HomeHandle,
pipe: *uvll::uv_pipe_t,
priv outgoing: Chan<Result<~RtioPipe, IoError>>,
priv incoming: Port<Result<~RtioPipe, IoError>>,
priv outgoing: Sender<Result<~RtioPipe, IoError>>,
priv incoming: Receiver<Result<~RtioPipe, IoError>>,
}
pub struct PipeAcceptor {
@ -182,12 +182,12 @@ impl PipeListener {
// If successful, unwrap the PipeWatcher because we control how
// we close the pipe differently. We can't rely on
// StreamWatcher's default close method.
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let p = ~PipeListener {
home: io.make_handle(),
pipe: pipe.unwrap(),
incoming: port,
outgoing: chan,
incoming: rx,
outgoing: tx,
};
Ok(p.install())
}
@ -299,19 +299,19 @@ mod tests {
fn connect() {
let path = next_test_unix();
let path2 = path.clone();
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap();
let mut p = p.listen().unwrap();
chan.send(());
tx.send(());
let mut client = p.accept().unwrap();
let mut buf = [0];
assert!(client.read(buf).unwrap() == 1);
assert_eq!(buf[0], 1);
assert!(client.write([2]).is_ok());
});
port.recv();
rx.recv();
let mut c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap();
assert!(c.write([1]).is_ok());
let mut buf = [0];
@ -323,15 +323,15 @@ mod tests {
fn connect_fail() {
let path = next_test_unix();
let path2 = path.clone();
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap();
let mut p = p.listen().unwrap();
chan.send(());
tx.send(());
drop(p.accept().unwrap());
});
port.recv();
rx.recv();
let _c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap();
fail!()

View File

@ -21,13 +21,13 @@ pub struct SignalWatcher {
handle: *uvll::uv_signal_t,
home: HomeHandle,
channel: Chan<Signum>,
channel: Sender<Signum>,
signal: Signum,
}
impl SignalWatcher {
pub fn new(io: &mut UvIoFactory, signum: Signum,
channel: Chan<Signum>) -> Result<~SignalWatcher, UvError> {
channel: Sender<Signum>) -> Result<~SignalWatcher, UvError> {
let s = ~SignalWatcher {
handle: UvHandle::alloc(None::<SignalWatcher>, uvll::UV_SIGNAL),
home: io.make_handle(),
@ -80,12 +80,12 @@ mod test {
#[test]
fn closing_channel_during_drop_doesnt_kill_everything() {
// see issue #10375, relates to timers as well.
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let _signal = SignalWatcher::new(local_loop(), signal::Interrupt,
chan);
tx);
spawn(proc() {
let _ = port.recv_opt();
let _ = rx.recv_opt();
});
// when we drop the SignalWatcher we're going to destroy the channel,

View File

@ -28,8 +28,8 @@ pub struct TimerWatcher {
pub enum NextAction {
WakeTask,
SendOnce(Chan<()>),
SendMany(Chan<()>, uint),
SendOnce(Sender<()>),
SendMany(Sender<()>, uint),
}
impl TimerWatcher {
@ -97,8 +97,8 @@ impl RtioTimer for TimerWatcher {
self.stop();
}
fn oneshot(&mut self, msecs: u64) -> Port<()> {
let (port, chan) = Chan::new();
fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
let (tx, rx) = channel();
// similarly to the destructor, we must drop the previous action outside
// of the homing missile
@ -107,14 +107,14 @@ impl RtioTimer for TimerWatcher {
self.id += 1;
self.stop();
self.start(msecs, 0);
mem::replace(&mut self.action, Some(SendOnce(chan)))
mem::replace(&mut self.action, Some(SendOnce(tx)))
};
return port;
return rx;
}
fn period(&mut self, msecs: u64) -> Port<()> {
let (port, chan) = Chan::new();
fn period(&mut self, msecs: u64) -> Receiver<()> {
let (tx, rx) = channel();
// similarly to the destructor, we must drop the previous action outside
// of the homing missile
@ -123,10 +123,10 @@ impl RtioTimer for TimerWatcher {
self.id += 1;
self.stop();
self.start(msecs, msecs);
mem::replace(&mut self.action, Some(SendMany(chan, self.id)))
mem::replace(&mut self.action, Some(SendMany(tx, self.id)))
};
return port;
return rx;
}
}

View File

@ -311,7 +311,7 @@ impl IoFactory for UvIoFactory {
}
}
fn signal(&mut self, signum: Signum, channel: Chan<Signum>)
fn signal(&mut self, signum: Signum, channel: Sender<Signum>)
-> Result<~rtio::RtioSignal, IoError> {
match SignalWatcher::new(self, signum, channel) {
Ok(s) => Ok(s as ~rtio::RtioSignal),

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@
/// The one caveat to consider is that when a port sees a disconnected channel
/// it must check for data because there is no "data plus upgrade" state.
use comm::Port;
use comm::Receiver;
use kinds::Send;
use mem;
use ops::Drop;
@ -60,7 +60,7 @@ pub struct Packet<T> {
pub enum Failure<T> {
Empty,
Disconnected,
Upgraded(Port<T>),
Upgraded(Receiver<T>),
}
pub enum UpgradeResult {
@ -71,14 +71,14 @@ pub enum UpgradeResult {
pub enum SelectionResult<T> {
SelCanceled(BlockedTask),
SelUpgraded(BlockedTask, Port<T>),
SelUpgraded(BlockedTask, Receiver<T>),
SelSuccess,
}
enum MyUpgrade<T> {
NothingSent,
SendUsed,
GoUp(Port<T>),
GoUp(Receiver<T>),
}
impl<T: Send> Packet<T> {
@ -201,7 +201,7 @@ impl<T: Send> Packet<T> {
// Returns whether the upgrade was completed. If the upgrade wasn't
// completed, then the port couldn't get sent to the other half (it will
// never receive it).
pub fn upgrade(&mut self, up: Port<T>) -> UpgradeResult {
pub fn upgrade(&mut self, up: Receiver<T>) -> UpgradeResult {
let prev = match self.upgrade {
NothingSent => NothingSent,
SendUsed => SendUsed,
@ -259,7 +259,7 @@ impl<T: Send> Packet<T> {
// If Ok, the value is whether this port has data, if Err, then the upgraded
// port needs to be checked instead of this one.
pub fn can_recv(&mut self) -> Result<bool, Port<T>> {
pub fn can_recv(&mut self) -> Result<bool, Receiver<T>> {
match self.state.load(atomics::SeqCst) {
EMPTY => Ok(false), // Welp, we tried
DATA => Ok(true), // we have some un-acquired data
@ -318,7 +318,7 @@ impl<T: Send> Packet<T> {
// blocked task will no longer be visible to any other threads.
//
// The return value indicates whether there's data on this port.
pub fn abort_selection(&mut self) -> Result<bool, Port<T>> {
pub fn abort_selection(&mut self) -> Result<bool, Receiver<T>> {
let state = match self.state.load(atomics::SeqCst) {
// Each of these states means that no further activity will happen
// with regard to abortion selection

View File

@ -8,38 +8,39 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Selection over an array of ports
//! Selection over an array of receivers
//!
//! This module contains the implementation machinery necessary for selecting
//! over a number of ports. One large goal of this module is to provide an
//! efficient interface to selecting over any port of any type.
//! over a number of receivers. One large goal of this module is to provide an
//! efficient interface to selecting over any receiver of any type.
//!
//! This is achieved through an architecture of a "port set" in which ports are
//! added to a set and then the entire set is waited on at once. The set can be
//! waited on multiple times to prevent re-adding each port to the set.
//! This is achieved through an architecture of a "receiver set" in which
//! receivers are added to a set and then the entire set is waited on at once.
//! The set can be waited on multiple times to prevent re-adding each receiver
//! to the set.
//!
//! Usage of this module is currently encouraged to go through the use of the
//! `select!` macro. This macro allows naturally binding of variables to the
//! received values of ports in a much more natural syntax then usage of the
//! received values of receivers in a much more natural syntax then usage of the
//! `Select` structure directly.
//!
//! # Example
//!
//! ```rust,ignore
//! let (mut p1, c1) = Chan::new();
//! let (mut p2, c2) = Chan::new();
//! ```rust
//! let (tx1, rx1) = channel();
//! let (tx2, rx2) = channel();
//!
//! c1.send(1);
//! c2.send(2);
//! tx1.send(1);
//! tx2.send(2);
//!
//! select! (
//! val = p1.recv() => {
//! select! {
//! val = rx1.recv() => {
//! assert_eq!(val, 1);
//! }
//! val = p2.recv() => {
//! },
//! val = rx2.recv() => {
//! assert_eq!(val, 2);
//! }
//! )
//! }
//! ```
#[allow(dead_code)];
@ -55,11 +56,11 @@ use ptr::RawPtr;
use result::{Ok, Err, Result};
use rt::local::Local;
use rt::task::{Task, BlockedTask};
use super::Port;
use super::Receiver;
use uint;
/// The "port set" of the select interface. This structure is used to manage a
/// set of ports which are being selected over.
/// The "receiver set" of the select interface. This structure is used to manage
/// a set of receivers which are being selected over.
pub struct Select {
priv head: *mut Handle<'static, ()>,
priv tail: *mut Handle<'static, ()>,
@ -68,22 +69,22 @@ pub struct Select {
priv marker2: marker::NoFreeze,
}
/// A handle to a port which is currently a member of a `Select` set of ports.
/// This handle is used to keep the port in the set as well as interact with the
/// underlying port.
pub struct Handle<'port, T> {
/// A handle to a receiver which is currently a member of a `Select` set of
/// receivers. This handle is used to keep the receiver in the set as well as
/// interact with the underlying receiver.
pub struct Handle<'rx, T> {
/// The ID of this handle, used to compare against the return value of
/// `Select::wait()`
priv id: uint,
priv selector: &'port Select,
priv selector: &'rx Select,
priv next: *mut Handle<'static, ()>,
priv prev: *mut Handle<'static, ()>,
priv added: bool,
priv packet: &'port Packet,
priv packet: &'rx Packet,
// due to our fun transmutes, we be sure to place this at the end. (nothing
// previous relies on T)
priv port: &'port Port<T>,
priv rx: &'rx Receiver<T>,
}
struct Packets { cur: *mut Handle<'static, ()> }
@ -111,10 +112,10 @@ impl Select {
}
}
/// Creates a new handle into this port set for a new port. Note that this
/// does *not* add the port to the port set, for that you must call the
/// `add` method on the handle itself.
pub fn handle<'a, T: Send>(&'a self, port: &'a Port<T>) -> Handle<'a, T> {
/// Creates a new handle into this receiver set for a new receiver. Note
/// that this does *not* add the receiver to the receiver set, for that you
/// must call the `add` method on the handle itself.
pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
let id = self.next_id.get();
self.next_id.set(id + 1);
Handle {
@ -123,12 +124,12 @@ impl Select {
next: 0 as *mut Handle<'static, ()>,
prev: 0 as *mut Handle<'static, ()>,
added: false,
port: port,
packet: port,
rx: rx,
packet: rx,
}
}
/// Waits for an event on this port set. The returned value is *not* an
/// Waits for an event on this receiver set. The returned value is *not* an
/// index, but rather an id. This id can be queried against any active
/// `Handle` structures (each one has an `id` method). The handle with
/// the matching `id` will have some sort of event available on it. The
@ -141,24 +142,24 @@ impl Select {
/// Helper method for skipping the preflight checks during testing
fn wait2(&self, do_preflight_checks: bool) -> uint {
// Note that this is currently an inefficient implementation. We in
// theory have knowledge about all ports in the set ahead of time, so
// this method shouldn't really have to iterate over all of them yet
// again. The idea with this "port set" interface is to get the
// theory have knowledge about all receivers in the set ahead of time,
// so this method shouldn't really have to iterate over all of them yet
// again. The idea with this "receiver set" interface is to get the
// interface right this time around, and later this implementation can
// be optimized.
//
// This implementation can be summarized by:
//
// fn select(ports) {
// if any port ready { return ready index }
// fn select(receivers) {
// if any receiver ready { return ready index }
// deschedule {
// block on all ports
// block on all receivers
// }
// unblock on all ports
// unblock on all receivers
// return ready index
// }
//
// Most notably, the iterations over all of the ports shouldn't be
// Most notably, the iterations over all of the receivers shouldn't be
// necessary.
unsafe {
let mut amt = 0;
@ -176,7 +177,7 @@ impl Select {
// Acquire a number of blocking contexts, and block on each one
// sequentially until one fails. If one fails, then abort
// immediately so we can go unblock on all the other ports.
// immediately so we can go unblock on all the other receivers.
let task: ~Task = Local::take();
task.deschedule(amt, |task| {
// Prepare for the block
@ -191,18 +192,18 @@ impl Select {
}
});
// Abort the selection process on each port. If the abort process
// returns `true`, then that means that the port is ready to receive
// some data. Note that this also means that the port may have yet
// to have fully read the `to_wake` field and woken us up (although
// the wakeup is guaranteed to fail).
// Abort the selection process on each receiver. If the abort
// process returns `true`, then that means that the receiver is
// ready to receive some data. Note that this also means that the
// receiver may have yet to have fully read the `to_wake` field and
// woken us up (although the wakeup is guaranteed to fail).
//
// This situation happens in the window of where a sender invokes
// increment(), sees -1, and then decides to wake up the task. After
// all this is done, the sending thread will set `selecting` to
// `false`. Until this is done, we cannot return. If we were to
// return, then a sender could wake up a port which has gone back to
// sleep after this call to `select`.
// return, then a sender could wake up a receiver which has gone
// back to sleep after this call to `select`.
//
// Note that it is a "fairly small window" in which an increment()
// views that it should wake a thread up until the `selecting` bit
@ -226,20 +227,20 @@ impl Select {
fn iter(&self) -> Packets { Packets { cur: self.head } }
}
impl<'port, T: Send> Handle<'port, T> {
impl<'rx, T: Send> Handle<'rx, T> {
/// Retrieve the id of this handle.
#[inline]
pub fn id(&self) -> uint { self.id }
/// Receive a value on the underlying port. Has the same semantics as
/// `Port.recv`
pub fn recv(&mut self) -> T { self.port.recv() }
/// Block to receive a value on the underlying port, returning `Some` on
/// Receive a value on the underlying receiver. Has the same semantics as
/// `Receiver.recv`
pub fn recv(&mut self) -> T { self.rx.recv() }
/// Block to receive a value on the underlying receiver, returning `Some` on
/// success or `None` if the channel disconnects. This function has the same
/// semantics as `Port.recv_opt`
pub fn recv_opt(&mut self) -> Option<T> { self.port.recv_opt() }
/// semantics as `Receiver.recv_opt`
pub fn recv_opt(&mut self) -> Option<T> { self.rx.recv_opt() }
/// Adds this handle to the port set that the handle was created from. This
/// Adds this handle to the receiver set that the handle was created from. This
/// method can be called multiple times, but it has no effect if `add` was
/// called previously.
///
@ -300,7 +301,7 @@ impl Drop for Select {
}
#[unsafe_destructor]
impl<'port, T: Send> Drop for Handle<'port, T> {
impl<'rx, T: Send> Drop for Handle<'rx, T> {
fn drop(&mut self) {
unsafe { self.remove() }
}
@ -325,328 +326,328 @@ mod test {
use prelude::*;
test!(fn smoke() {
let (p1, c1) = Chan::<int>::new();
let (p2, c2) = Chan::<int>::new();
c1.send(1);
let (tx1, rx1) = channel::<int>();
let (tx2, rx2) = channel::<int>();
tx1.send(1);
select! (
foo = p1.recv() => { assert_eq!(foo, 1); },
_bar = p2.recv() => { fail!() }
foo = rx1.recv() => { assert_eq!(foo, 1); },
_bar = rx2.recv() => { fail!() }
)
c2.send(2);
tx2.send(2);
select! (
_foo = p1.recv() => { fail!() },
bar = p2.recv() => { assert_eq!(bar, 2) }
_foo = rx1.recv() => { fail!() },
bar = rx2.recv() => { assert_eq!(bar, 2) }
)
drop(c1);
drop(tx1);
select! (
foo = p1.recv_opt() => { assert_eq!(foo, None); },
_bar = p2.recv() => { fail!() }
foo = rx1.recv_opt() => { assert_eq!(foo, None); },
_bar = rx2.recv() => { fail!() }
)
drop(c2);
drop(tx2);
select! (
bar = p2.recv_opt() => { assert_eq!(bar, None); }
bar = rx2.recv_opt() => { assert_eq!(bar, None); }
)
})
test!(fn smoke2() {
let (p1, _c1) = Chan::<int>::new();
let (p2, _c2) = Chan::<int>::new();
let (p3, _c3) = Chan::<int>::new();
let (p4, _c4) = Chan::<int>::new();
let (p5, c5) = Chan::<int>::new();
c5.send(4);
let (_tx1, rx1) = channel::<int>();
let (_tx2, rx2) = channel::<int>();
let (_tx3, rx3) = channel::<int>();
let (_tx4, rx4) = channel::<int>();
let (tx5, rx5) = channel::<int>();
tx5.send(4);
select! (
_foo = p1.recv() => { fail!("1") },
_foo = p2.recv() => { fail!("2") },
_foo = p3.recv() => { fail!("3") },
_foo = p4.recv() => { fail!("4") },
foo = p5.recv() => { assert_eq!(foo, 4); }
_foo = rx1.recv() => { fail!("1") },
_foo = rx2.recv() => { fail!("2") },
_foo = rx3.recv() => { fail!("3") },
_foo = rx4.recv() => { fail!("4") },
foo = rx5.recv() => { assert_eq!(foo, 4); }
)
})
test!(fn closed() {
let (p1, _c1) = Chan::<int>::new();
let (p2, c2) = Chan::<int>::new();
drop(c2);
let (_tx1, rx1) = channel::<int>();
let (tx2, rx2) = channel::<int>();
drop(tx2);
select! (
_a1 = p1.recv_opt() => { fail!() },
a2 = p2.recv_opt() => { assert_eq!(a2, None); }
_a1 = rx1.recv_opt() => { fail!() },
a2 = rx2.recv_opt() => { assert_eq!(a2, None); }
)
})
test!(fn unblocks() {
let (p1, c1) = Chan::<int>::new();
let (p2, _c2) = Chan::<int>::new();
let (p3, c3) = Chan::<int>::new();
let (tx1, rx1) = channel::<int>();
let (_tx2, rx2) = channel::<int>();
let (tx3, rx3) = channel::<int>();
spawn(proc() {
for _ in range(0, 20) { task::deschedule(); }
c1.send(1);
p3.recv();
tx1.send(1);
rx3.recv();
for _ in range(0, 20) { task::deschedule(); }
});
select! (
a = p1.recv() => { assert_eq!(a, 1); },
_b = p2.recv() => { fail!() }
a = rx1.recv() => { assert_eq!(a, 1); },
_b = rx2.recv() => { fail!() }
)
c3.send(1);
tx3.send(1);
select! (
a = p1.recv_opt() => { assert_eq!(a, None); },
_b = p2.recv() => { fail!() }
a = rx1.recv_opt() => { assert_eq!(a, None); },
_b = rx2.recv() => { fail!() }
)
})
test!(fn both_ready() {
let (p1, c1) = Chan::<int>::new();
let (p2, c2) = Chan::<int>::new();
let (p3, c3) = Chan::<()>::new();
let (tx1, rx1) = channel::<int>();
let (tx2, rx2) = channel::<int>();
let (tx3, rx3) = channel::<()>();
spawn(proc() {
for _ in range(0, 20) { task::deschedule(); }
c1.send(1);
c2.send(2);
p3.recv();
tx1.send(1);
tx2.send(2);
rx3.recv();
});
select! (
a = p1.recv() => { assert_eq!(a, 1); },
a = p2.recv() => { assert_eq!(a, 2); }
a = rx1.recv() => { assert_eq!(a, 1); },
a = rx2.recv() => { assert_eq!(a, 2); }
)
select! (
a = p1.recv() => { assert_eq!(a, 1); },
a = p2.recv() => { assert_eq!(a, 2); }
a = rx1.recv() => { assert_eq!(a, 1); },
a = rx2.recv() => { assert_eq!(a, 2); }
)
assert_eq!(p1.try_recv(), Empty);
assert_eq!(p2.try_recv(), Empty);
c3.send(());
assert_eq!(rx1.try_recv(), Empty);
assert_eq!(rx2.try_recv(), Empty);
tx3.send(());
})
test!(fn stress() {
static AMT: int = 10000;
let (p1, c1) = Chan::<int>::new();
let (p2, c2) = Chan::<int>::new();
let (p3, c3) = Chan::<()>::new();
let (tx1, rx1) = channel::<int>();
let (tx2, rx2) = channel::<int>();
let (tx3, rx3) = channel::<()>();
spawn(proc() {
for i in range(0, AMT) {
if i % 2 == 0 {
c1.send(i);
tx1.send(i);
} else {
c2.send(i);
tx2.send(i);
}
p3.recv();
rx3.recv();
}
});
for i in range(0, AMT) {
select! (
i1 = p1.recv() => { assert!(i % 2 == 0 && i == i1); },
i2 = p2.recv() => { assert!(i % 2 == 1 && i == i2); }
i1 = rx1.recv() => { assert!(i % 2 == 0 && i == i1); },
i2 = rx2.recv() => { assert!(i % 2 == 1 && i == i2); }
)
c3.send(());
tx3.send(());
}
})
test!(fn cloning() {
let (p1, c1) = Chan::<int>::new();
let (p2, _c2) = Chan::<int>::new();
let (p3, c3) = Chan::<()>::new();
let (tx1, rx1) = channel::<int>();
let (_tx2, rx2) = channel::<int>();
let (tx3, rx3) = channel::<()>();
spawn(proc() {
p3.recv();
c1.clone();
assert_eq!(p3.try_recv(), Empty);
c1.send(2);
p3.recv();
rx3.recv();
tx1.clone();
assert_eq!(rx3.try_recv(), Empty);
tx1.send(2);
rx3.recv();
});
c3.send(());
tx3.send(());
select!(
_i1 = p1.recv() => {},
_i2 = p2.recv() => fail!()
_i1 = rx1.recv() => {},
_i2 = rx2.recv() => fail!()
)
c3.send(());
tx3.send(());
})
test!(fn cloning2() {
let (p1, c1) = Chan::<int>::new();
let (p2, _c2) = Chan::<int>::new();
let (p3, c3) = Chan::<()>::new();
let (tx1, rx1) = channel::<int>();
let (_tx2, rx2) = channel::<int>();
let (tx3, rx3) = channel::<()>();
spawn(proc() {
p3.recv();
c1.clone();
assert_eq!(p3.try_recv(), Empty);
c1.send(2);
p3.recv();
rx3.recv();
tx1.clone();
assert_eq!(rx3.try_recv(), Empty);
tx1.send(2);
rx3.recv();
});
c3.send(());
tx3.send(());
select!(
_i1 = p1.recv() => {},
_i2 = p2.recv() => fail!()
_i1 = rx1.recv() => {},
_i2 = rx2.recv() => fail!()
)
c3.send(());
tx3.send(());
})
test!(fn cloning3() {
let (p1, c1) = Chan::<()>::new();
let (p2, c2) = Chan::<()>::new();
let (p, c) = Chan::new();
let (tx1, rx1) = channel::<()>();
let (tx2, rx2) = channel::<()>();
let (tx3, rx3) = channel::<()>();
spawn(proc() {
let s = Select::new();
let mut h1 = s.handle(&p1);
let mut h2 = s.handle(&p2);
let mut h1 = s.handle(&rx1);
let mut h2 = s.handle(&rx2);
unsafe { h2.add(); }
unsafe { h1.add(); }
assert_eq!(s.wait(), h2.id);
c.send(());
tx3.send(());
});
for _ in range(0, 1000) { task::deschedule(); }
drop(c1.clone());
c2.send(());
p.recv();
drop(tx1.clone());
tx2.send(());
rx3.recv();
})
test!(fn preflight1() {
let (p, c) = Chan::new();
c.send(());
let (tx, rx) = channel();
tx.send(());
select!(
() = p.recv() => {}
() = rx.recv() => {}
)
})
test!(fn preflight2() {
let (p, c) = Chan::new();
c.send(());
c.send(());
let (tx, rx) = channel();
tx.send(());
tx.send(());
select!(
() = p.recv() => {}
() = rx.recv() => {}
)
})
test!(fn preflight3() {
let (p, c) = Chan::new();
drop(c.clone());
c.send(());
let (tx, rx) = channel();
drop(tx.clone());
tx.send(());
select!(
() = p.recv() => {}
() = rx.recv() => {}
)
})
test!(fn preflight4() {
let (p, c) = Chan::new();
c.send(());
let (tx, rx) = channel();
tx.send(());
let s = Select::new();
let mut h = s.handle(&p);
let mut h = s.handle(&rx);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight5() {
let (p, c) = Chan::new();
c.send(());
c.send(());
let (tx, rx) = channel();
tx.send(());
tx.send(());
let s = Select::new();
let mut h = s.handle(&p);
let mut h = s.handle(&rx);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight6() {
let (p, c) = Chan::new();
drop(c.clone());
c.send(());
let (tx, rx) = channel();
drop(tx.clone());
tx.send(());
let s = Select::new();
let mut h = s.handle(&p);
let mut h = s.handle(&rx);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight7() {
let (p, c) = Chan::<()>::new();
drop(c);
let (tx, rx) = channel::<()>();
drop(tx);
let s = Select::new();
let mut h = s.handle(&p);
let mut h = s.handle(&rx);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight8() {
let (p, c) = Chan::new();
c.send(());
drop(c);
p.recv();
let (tx, rx) = channel();
tx.send(());
drop(tx);
rx.recv();
let s = Select::new();
let mut h = s.handle(&p);
let mut h = s.handle(&rx);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight9() {
let (p, c) = Chan::new();
drop(c.clone());
c.send(());
drop(c);
p.recv();
let (tx, rx) = channel();
drop(tx.clone());
tx.send(());
drop(tx);
rx.recv();
let s = Select::new();
let mut h = s.handle(&p);
let mut h = s.handle(&rx);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn oneshot_data_waiting() {
let (p, c) = Chan::new();
let (p2, c2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
spawn(proc() {
select! {
() = p.recv() => {}
() = rx1.recv() => {}
}
c2.send(());
tx2.send(());
});
for _ in range(0, 100) { task::deschedule() }
c.send(());
p2.recv();
tx1.send(());
rx2.recv();
})
test!(fn stream_data_waiting() {
let (p, c) = Chan::new();
let (p2, c2) = Chan::new();
c.send(());
c.send(());
p.recv();
p.recv();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
tx1.send(());
tx1.send(());
rx1.recv();
rx1.recv();
spawn(proc() {
select! {
() = p.recv() => {}
() = rx1.recv() => {}
}
c2.send(());
tx2.send(());
});
for _ in range(0, 100) { task::deschedule() }
c.send(());
p2.recv();
tx1.send(());
rx2.recv();
})
test!(fn shared_data_waiting() {
let (p, c) = Chan::new();
let (p2, c2) = Chan::new();
drop(c.clone());
c.send(());
p.recv();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
drop(tx1.clone());
tx1.send(());
rx1.recv();
spawn(proc() {
select! {
() = p.recv() => {}
() = rx1.recv() => {}
}
c2.send(());
tx2.send(());
});
for _ in range(0, 100) { task::deschedule() }
c.send(());
p2.recv();
tx1.send(());
rx2.recv();
})
}

View File

@ -18,7 +18,7 @@
/// module.
use cmp;
use comm::Port;
use comm::Receiver;
use int;
use iter::Iterator;
use kinds::Send;
@ -51,7 +51,7 @@ pub struct Packet<T> {
pub enum Failure<T> {
Empty,
Disconnected,
Upgraded(Port<T>),
Upgraded(Receiver<T>),
}
pub enum UpgradeResult {
@ -63,14 +63,14 @@ pub enum UpgradeResult {
pub enum SelectionResult<T> {
SelSuccess,
SelCanceled(BlockedTask),
SelUpgraded(BlockedTask, Port<T>),
SelUpgraded(BlockedTask, Receiver<T>),
}
// Any message could contain an "upgrade request" to a new shared port, so the
// internal queue it's a queue of T, but rather Message<T>
enum Message<T> {
Data(T),
GoUp(Port<T>),
GoUp(Receiver<T>),
}
impl<T: Send> Packet<T> {
@ -97,7 +97,7 @@ impl<T: Send> Packet<T> {
}
}
}
pub fn upgrade(&mut self, up: Port<T>) -> UpgradeResult {
pub fn upgrade(&mut self, up: Receiver<T>) -> UpgradeResult {
self.do_send(GoUp(up))
}
@ -328,7 +328,7 @@ impl<T: Send> Packet<T> {
// Tests to see whether this port can receive without blocking. If Ok is
// returned, then that's the answer. If Err is returned, then the returned
// port needs to be queried instead (an upgrade happened)
pub fn can_recv(&mut self) -> Result<bool, Port<T>> {
pub fn can_recv(&mut self) -> Result<bool, Receiver<T>> {
// We peek at the queue to see if there's anything on it, and we use
// this return value to determine if we should pop from the queue and
// upgrade this channel immediately. If it looks like we've got an
@ -384,7 +384,7 @@ impl<T: Send> Packet<T> {
// Removes a previous task from being blocked in this port
pub fn abort_selection(&mut self,
was_upgrade: bool) -> Result<bool, Port<T>> {
was_upgrade: bool) -> Result<bool, Receiver<T>> {
// If we're aborting selection after upgrading from a oneshot, then
// we're guarantee that no one is waiting. The only way that we could
// have seen the upgrade is if data was actually sent on the channel

View File

@ -8,25 +8,26 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use prelude::*;
use comm::{Port, Chan};
use clone::Clone;
use cmp;
use container::Container;
use comm::{Sender, Receiver};
use io;
use option::{None, Option, Some};
use result::{Ok, Err};
use super::{Reader, Writer, IoResult};
use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
/// Allows reading from a port.
/// Allows reading from a rx.
///
/// # Example
///
/// ```
/// use std::io::PortReader;
/// use std::io::ChanReader;
///
/// let (port, chan) = Chan::new();
/// # drop(chan);
/// let mut reader = PortReader::new(port);
/// let (tx, rx) = channel();
/// # drop(tx);
/// let mut reader = ChanReader::new(rx);
///
/// let mut buf = ~[0u8, ..100];
/// match reader.read(buf) {
@ -34,26 +35,26 @@ use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
/// Err(e) => println!("read error: {}", e),
/// }
/// ```
pub struct PortReader {
pub struct ChanReader {
priv buf: Option<~[u8]>, // A buffer of bytes received but not consumed.
priv pos: uint, // How many of the buffered bytes have already be consumed.
priv port: Port<~[u8]>, // The port to pull data from.
priv closed: bool, // Whether the pipe this port connects to has been closed.
priv rx: Receiver<~[u8]>, // The rx to pull data from.
priv closed: bool, // Whether the pipe this rx connects to has been closed.
}
impl PortReader {
/// Wraps a `Port` in a `PortReader` structure
pub fn new(port: Port<~[u8]>) -> PortReader {
PortReader {
impl ChanReader {
/// Wraps a `Port` in a `ChanReader` structure
pub fn new(rx: Receiver<~[u8]>) -> ChanReader {
ChanReader {
buf: None,
pos: 0,
port: port,
rx: rx,
closed: false,
}
}
}
impl Reader for PortReader {
impl Reader for ChanReader {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
let mut num_read = 0;
loop {
@ -72,7 +73,7 @@ impl Reader for PortReader {
break;
}
self.pos = 0;
self.buf = self.port.recv_opt();
self.buf = self.rx.recv_opt();
self.closed = self.buf.is_none();
}
if self.closed && num_read == 0 {
@ -83,7 +84,7 @@ impl Reader for PortReader {
}
}
/// Allows writing to a chan.
/// Allows writing to a tx.
///
/// # Example
///
@ -91,31 +92,31 @@ impl Reader for PortReader {
/// # #[allow(unused_must_use)];
/// use std::io::ChanWriter;
///
/// let (port, chan) = Chan::new();
/// # drop(port);
/// let mut writer = ChanWriter::new(chan);
/// let (tx, rx) = channel();
/// # drop(rx);
/// let mut writer = ChanWriter::new(tx);
/// writer.write("hello, world".as_bytes());
/// ```
pub struct ChanWriter {
priv chan: Chan<~[u8]>,
priv tx: Sender<~[u8]>,
}
impl ChanWriter {
/// Wraps a channel in a `ChanWriter` structure
pub fn new(chan: Chan<~[u8]>) -> ChanWriter {
ChanWriter { chan: chan }
pub fn new(tx: Sender<~[u8]>) -> ChanWriter {
ChanWriter { tx: tx }
}
}
impl Clone for ChanWriter {
fn clone(&self) -> ChanWriter {
ChanWriter { chan: self.chan.clone() }
ChanWriter { tx: self.tx.clone() }
}
}
impl Writer for ChanWriter {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
if !self.chan.try_send(buf.to_owned()) {
if !self.tx.try_send(buf.to_owned()) {
Err(io::IoError {
kind: io::BrokenPipe,
desc: "Pipe closed",
@ -136,17 +137,17 @@ mod test {
use task;
#[test]
fn test_port_reader() {
let (port, chan) = Chan::new();
fn test_rx_reader() {
let (tx, rx) = channel();
task::spawn(proc() {
chan.send(~[1u8, 2u8]);
chan.send(~[]);
chan.send(~[3u8, 4u8]);
chan.send(~[5u8, 6u8]);
chan.send(~[7u8, 8u8]);
tx.send(~[1u8, 2u8]);
tx.send(~[]);
tx.send(~[3u8, 4u8]);
tx.send(~[5u8, 6u8]);
tx.send(~[7u8, 8u8]);
});
let mut reader = PortReader::new(port);
let mut reader = ChanReader::new(rx);
let mut buf = ~[0u8, ..3];
@ -177,12 +178,12 @@ mod test {
#[test]
fn test_chan_writer() {
let (port, chan) = Chan::new();
let mut writer = ChanWriter::new(chan);
let (tx, rx) = channel();
let mut writer = ChanWriter::new(tx);
writer.write_be_u32(42).unwrap();
let wanted = ~[0u8, 0u8, 0u8, 42u8];
let got = task::try(proc() { port.recv() }).unwrap();
let got = task::try(proc() { rx.recv() }).unwrap();
assert_eq!(wanted, got);
match writer.write_u8(1) {

View File

@ -245,7 +245,7 @@ pub use self::process::{Process, ProcessConfig};
pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
pub use self::buffered::{BufferedReader, BufferedWriter, BufferedStream,
LineBufferedWriter};
pub use self::comm_adapters::{PortReader, ChanWriter};
pub use self::comm_adapters::{ChanReader, ChanWriter};
pub mod test;

View File

@ -195,16 +195,13 @@ mod test {
iotest!(fn smoke_test_ip4() {
let addr = next_test_ip4();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let mut stream = TcpStream::connect(addr);
stream.write([99]).unwrap();
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
stream.read(buf).unwrap();
@ -213,16 +210,13 @@ mod test {
iotest!(fn smoke_test_ip6() {
let addr = next_test_ip6();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let mut stream = TcpStream::connect(addr);
stream.write([99]).unwrap();
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
stream.read(buf).unwrap();
@ -231,16 +225,13 @@ mod test {
iotest!(fn read_eof_ip4() {
let addr = next_test_ip4();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let _stream = TcpStream::connect(addr);
// Close
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
let nread = stream.read(buf);
@ -249,16 +240,13 @@ mod test {
iotest!(fn read_eof_ip6() {
let addr = next_test_ip6();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let _stream = TcpStream::connect(addr);
// Close
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
let nread = stream.read(buf);
@ -267,16 +255,13 @@ mod test {
iotest!(fn read_eof_twice_ip4() {
let addr = next_test_ip4();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let _stream = TcpStream::connect(addr);
// Close
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
let nread = stream.read(buf);
@ -293,16 +278,13 @@ mod test {
iotest!(fn read_eof_twice_ip6() {
let addr = next_test_ip6();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let _stream = TcpStream::connect(addr);
// Close
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
let nread = stream.read(buf);
@ -319,16 +301,13 @@ mod test {
iotest!(fn write_close_ip4() {
let addr = next_test_ip4();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let _stream = TcpStream::connect(addr);
// Close
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let buf = [0];
loop {
@ -347,16 +326,13 @@ mod test {
iotest!(fn write_close_ip6() {
let addr = next_test_ip6();
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
let _stream = TcpStream::connect(addr);
// Close
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let buf = [0];
loop {
@ -376,18 +352,15 @@ mod test {
iotest!(fn multiple_connect_serial_ip4() {
let addr = next_test_ip4();
let max = 10u;
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
for _ in range(0, max) {
let mut stream = TcpStream::connect(addr);
stream.write([99]).unwrap();
}
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
for ref mut stream in acceptor.incoming().take(max) {
let mut buf = [0];
stream.read(buf).unwrap();
@ -398,18 +371,15 @@ mod test {
iotest!(fn multiple_connect_serial_ip6() {
let addr = next_test_ip6();
let max = 10u;
let (port, chan) = Chan::new();
let mut acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
port.recv();
for _ in range(0, max) {
let mut stream = TcpStream::connect(addr);
stream.write([99]).unwrap();
}
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
for ref mut stream in acceptor.incoming().take(max) {
let mut buf = [0];
stream.read(buf).unwrap();
@ -420,11 +390,10 @@ mod test {
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip4() {
let addr = next_test_ip4();
static MAX: int = 10;
let (port, chan) = Chan::new();
let acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut acceptor = acceptor;
for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
// Start another task to handle the connection
spawn(proc() {
@ -437,7 +406,6 @@ mod test {
}
});
port.recv();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
@ -457,11 +425,10 @@ mod test {
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip6() {
let addr = next_test_ip6();
static MAX: int = 10;
let (port, chan) = Chan::<()>::new();
let acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut acceptor = acceptor;
for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
// Start another task to handle the connection
spawn(proc() {
@ -474,7 +441,6 @@ mod test {
}
});
port.recv();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
@ -492,13 +458,12 @@ mod test {
})
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip4() {
let addr = next_test_ip4();
static MAX: int = 10;
let (port, chan) = Chan::new();
let addr = next_test_ip4();
let acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut acceptor = acceptor;
for stream in acceptor.incoming().take(MAX as uint) {
// Start another task to handle the connection
spawn(proc() {
@ -511,7 +476,6 @@ mod test {
}
});
port.recv();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
@ -529,13 +493,12 @@ mod test {
})
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip6() {
let addr = next_test_ip6();
static MAX: int = 10;
let (port, chan) = Chan::new();
let addr = next_test_ip6();
let acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut acceptor = acceptor;
for stream in acceptor.incoming().take(MAX as uint) {
// Start another task to handle the connection
spawn(proc() {
@ -548,7 +511,6 @@ mod test {
}
});
port.recv();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
@ -576,15 +538,12 @@ mod test {
}
pub fn peer_name(addr: SocketAddr) {
let (port, chan) = Chan::new();
let acceptor = TcpListener::bind(addr).listen();
spawn(proc() {
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut acceptor = acceptor;
acceptor.accept().unwrap();
});
port.recv();
let stream = TcpStream::connect(addr);
assert!(stream.is_ok());
@ -611,23 +570,23 @@ mod test {
iotest!(fn partial_read() {
let addr = next_test_ip4();
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let mut srv = TcpListener::bind(addr).listen().unwrap();
c.send(());
tx.send(());
let mut cl = srv.accept().unwrap();
cl.write([10]).unwrap();
let mut b = [0];
cl.read(b).unwrap();
c.send(());
tx.send(());
});
p.recv();
rx.recv();
let mut c = TcpStream::connect(addr).unwrap();
let mut b = [0, ..10];
assert_eq!(c.read(b), Ok(1));
c.write([1]).unwrap();
p.recv();
rx.recv();
})
iotest!(fn double_bind() {
@ -644,22 +603,22 @@ mod test {
iotest!(fn fast_rebind() {
let addr = next_test_ip4();
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
port.recv();
rx.recv();
let _stream = TcpStream::connect(addr).unwrap();
// Close
port.recv();
rx.recv();
});
{
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
tx.send(());
{
let _stream = acceptor.accept().unwrap();
// Close client
chan.send(());
tx.send(());
}
// Close listener
}
@ -681,50 +640,50 @@ mod test {
let mut s1 = acceptor.accept().unwrap();
let s2 = s1.clone();
let (p1, c1) = Chan::new();
let (p2, c2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
spawn(proc() {
let mut s2 = s2;
p1.recv();
rx1.recv();
s2.write([1]).unwrap();
c2.send(());
tx2.send(());
});
c1.send(());
tx1.send(());
let mut buf = [0, 0];
assert_eq!(s1.read(buf), Ok(1));
p2.recv();
rx2.recv();
})
iotest!(fn tcp_clone_two_read() {
let addr = next_test_ip6();
let mut acceptor = TcpListener::bind(addr).listen();
let (p, c) = Chan::new();
let c2 = c.clone();
let (tx1, rx) = channel();
let tx2 = tx1.clone();
spawn(proc() {
let mut s = TcpStream::connect(addr);
s.write([1]).unwrap();
p.recv();
rx.recv();
s.write([2]).unwrap();
p.recv();
rx.recv();
});
let mut s1 = acceptor.accept().unwrap();
let s2 = s1.clone();
let (p, done) = Chan::new();
let (done, rx) = channel();
spawn(proc() {
let mut s2 = s2;
let mut buf = [0, 0];
s2.read(buf).unwrap();
c2.send(());
tx2.send(());
done.send(());
});
let mut buf = [0, 0];
s1.read(buf).unwrap();
c.send(());
tx1.send(());
p.recv();
rx.recv();
})
iotest!(fn tcp_clone_two_write() {
@ -741,7 +700,7 @@ mod test {
let mut s1 = acceptor.accept().unwrap();
let s2 = s1.clone();
let (p, done) = Chan::new();
let (done, rx) = channel();
spawn(proc() {
let mut s2 = s2;
s2.write([1]).unwrap();
@ -749,7 +708,7 @@ mod test {
});
s1.write([2]).unwrap();
p.recv();
rx.recv();
})
}

View File

@ -107,23 +107,23 @@ mod test {
iotest!(fn socket_smoke_test_ip4() {
let server_ip = next_test_ip4();
let client_ip = next_test_ip4();
let (port, chan) = Chan::new();
let (port2, chan2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
spawn(proc() {
match UdpSocket::bind(client_ip) {
Ok(ref mut client) => {
port.recv();
rx1.recv();
client.sendto([99], server_ip).unwrap()
}
Err(..) => fail!()
}
chan2.send(());
tx2.send(());
});
match UdpSocket::bind(server_ip) {
Ok(ref mut server) => {
chan.send(());
tx1.send(());
let mut buf = [0];
match server.recvfrom(buf) {
Ok((nread, src)) => {
@ -136,18 +136,18 @@ mod test {
}
Err(..) => fail!()
}
port2.recv();
rx2.recv();
})
iotest!(fn socket_smoke_test_ip6() {
let server_ip = next_test_ip6();
let client_ip = next_test_ip6();
let (port, chan) = Chan::<()>::new();
let (tx, rx) = channel::<()>();
spawn(proc() {
match UdpSocket::bind(client_ip) {
Ok(ref mut client) => {
port.recv();
rx.recv();
client.sendto([99], server_ip).unwrap()
}
Err(..) => fail!()
@ -156,7 +156,7 @@ mod test {
match UdpSocket::bind(server_ip) {
Ok(ref mut server) => {
chan.send(());
tx.send(());
let mut buf = [0];
match server.recvfrom(buf) {
Ok((nread, src)) => {
@ -174,27 +174,27 @@ mod test {
iotest!(fn stream_smoke_test_ip4() {
let server_ip = next_test_ip4();
let client_ip = next_test_ip4();
let (port, chan) = Chan::new();
let (port2, chan2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
spawn(proc() {
match UdpSocket::bind(client_ip) {
Ok(client) => {
let client = ~client;
let mut stream = client.connect(server_ip);
port.recv();
rx1.recv();
stream.write([99]).unwrap();
}
Err(..) => fail!()
}
chan2.send(());
tx2.send(());
});
match UdpSocket::bind(server_ip) {
Ok(server) => {
let server = ~server;
let mut stream = server.connect(client_ip);
chan.send(());
tx1.send(());
let mut buf = [0];
match stream.read(buf) {
Ok(nread) => {
@ -206,33 +206,33 @@ mod test {
}
Err(..) => fail!()
}
port2.recv();
rx2.recv();
})
iotest!(fn stream_smoke_test_ip6() {
let server_ip = next_test_ip6();
let client_ip = next_test_ip6();
let (port, chan) = Chan::new();
let (port2, chan2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
spawn(proc() {
match UdpSocket::bind(client_ip) {
Ok(client) => {
let client = ~client;
let mut stream = client.connect(server_ip);
port.recv();
rx1.recv();
stream.write([99]).unwrap();
}
Err(..) => fail!()
}
chan2.send(());
tx2.send(());
});
match UdpSocket::bind(server_ip) {
Ok(server) => {
let server = ~server;
let mut stream = server.connect(client_ip);
chan.send(());
tx1.send(());
let mut buf = [0];
match stream.read(buf) {
Ok(nread) => {
@ -244,7 +244,7 @@ mod test {
}
Err(..) => fail!()
}
port2.recv();
rx2.recv();
})
pub fn socket_name(addr: SocketAddr) {
@ -284,18 +284,18 @@ mod test {
let sock3 = sock1.clone();
let (p1, c1) = Chan::new();
let (p2, c2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
spawn(proc() {
let mut sock3 = sock3;
p1.recv();
rx1.recv();
sock3.sendto([1], addr2).unwrap();
c2.send(());
tx2.send(());
});
c1.send(());
tx1.send(());
let mut buf = [0, 0];
assert_eq!(sock1.recvfrom(buf), Ok((1, addr2)));
p2.recv();
rx2.recv();
})
iotest!(fn udp_clone_two_read() {
@ -303,32 +303,32 @@ mod test {
let addr2 = next_test_ip4();
let mut sock1 = UdpSocket::bind(addr1).unwrap();
let sock2 = UdpSocket::bind(addr2).unwrap();
let (p, c) = Chan::new();
let c2 = c.clone();
let (tx1, rx) = channel();
let tx2 = tx1.clone();
spawn(proc() {
let mut sock2 = sock2;
sock2.sendto([1], addr1).unwrap();
p.recv();
rx.recv();
sock2.sendto([2], addr1).unwrap();
p.recv();
rx.recv();
});
let sock3 = sock1.clone();
let (p, done) = Chan::new();
let (done, rx) = channel();
spawn(proc() {
let mut sock3 = sock3;
let mut buf = [0, 0];
sock3.recvfrom(buf).unwrap();
c2.send(());
tx2.send(());
done.send(());
});
let mut buf = [0, 0];
sock1.recvfrom(buf).unwrap();
c.send(());
tx1.send(());
p.recv();
rx.recv();
})
iotest!(fn udp_clone_two_write() {
@ -337,40 +337,40 @@ mod test {
let mut sock1 = UdpSocket::bind(addr1).unwrap();
let sock2 = UdpSocket::bind(addr2).unwrap();
let (p, c) = Chan::new();
let (serv_port, serv_chan) = Chan::new();
let (tx, rx) = channel();
let (serv_tx, serv_rx) = channel();
spawn(proc() {
let mut sock2 = sock2;
let mut buf = [0, 1];
p.recv();
rx.recv();
match sock2.recvfrom(buf) {
Ok(..) => {}
Err(e) => fail!("failed receive: {}", e),
}
serv_chan.send(());
serv_tx.send(());
});
let sock3 = sock1.clone();
let (p, done) = Chan::new();
let c2 = c.clone();
let (done, rx) = channel();
let tx2 = tx.clone();
spawn(proc() {
let mut sock3 = sock3;
match sock3.sendto([1], addr2) {
Ok(..) => { let _ = c2.try_send(()); }
Ok(..) => { let _ = tx2.try_send(()); }
Err(..) => {}
}
done.send(());
});
match sock1.sendto([2], addr2) {
Ok(..) => { let _ = c.try_send(()); }
Ok(..) => { let _ = tx.try_send(()); }
Err(..) => {}
}
drop(c);
drop(tx);
p.recv();
serv_port.recv();
rx.recv();
serv_rx.recv();
})
}

View File

@ -224,10 +224,13 @@ mod tests {
let times = 10;
let path1 = next_test_unix();
let path2 = path1.clone();
let (port, chan) = Chan::new();
let mut acceptor = match UnixListener::bind(&path1).listen() {
Ok(a) => a,
Err(e) => fail!("failed listen: {}", e),
};
spawn(proc() {
port.recv();
for _ in range(0, times) {
let mut stream = UnixStream::connect(&path2);
match stream.write([100]) {
@ -237,11 +240,6 @@ mod tests {
}
});
let mut acceptor = match UnixListener::bind(&path1).listen() {
Ok(a) => a,
Err(e) => fail!("failed listen: {}", e),
};
chan.send(());
for _ in range(0, times) {
let mut client = acceptor.accept();
let mut buf = [0];
@ -278,54 +276,54 @@ mod tests {
let mut s1 = acceptor.accept().unwrap();
let s2 = s1.clone();
let (p1, c1) = Chan::new();
let (p2, c2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
spawn(proc() {
let mut s2 = s2;
p1.recv();
rx1.recv();
debug!("writer writing");
s2.write([1]).unwrap();
debug!("writer done");
c2.send(());
tx2.send(());
});
c1.send(());
tx1.send(());
let mut buf = [0, 0];
debug!("reader reading");
assert_eq!(s1.read(buf), Ok(1));
debug!("reader done");
p2.recv();
rx2.recv();
})
iotest!(fn unix_clone_two_read() {
let addr = next_test_unix();
let mut acceptor = UnixListener::bind(&addr).listen();
let (p, c) = Chan::new();
let c2 = c.clone();
let (tx1, rx) = channel();
let tx2 = tx1.clone();
spawn(proc() {
let mut s = UnixStream::connect(&addr);
s.write([1]).unwrap();
p.recv();
rx.recv();
s.write([2]).unwrap();
p.recv();
rx.recv();
});
let mut s1 = acceptor.accept().unwrap();
let s2 = s1.clone();
let (p, done) = Chan::new();
let (done, rx) = channel();
spawn(proc() {
let mut s2 = s2;
let mut buf = [0, 0];
s2.read(buf).unwrap();
c2.send(());
tx2.send(());
done.send(());
});
let mut buf = [0, 0];
s1.read(buf).unwrap();
c.send(());
tx1.send(());
p.recv();
rx.recv();
})
iotest!(fn unix_clone_two_write() {
@ -342,14 +340,14 @@ mod tests {
let mut s1 = acceptor.accept().unwrap();
let s2 = s1.clone();
let (p, done) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let mut s2 = s2;
s2.write([1]).unwrap();
done.send(());
tx.send(());
});
s1.write([2]).unwrap();
p.recv();
rx.recv();
})
}

View File

@ -77,15 +77,15 @@ mod test {
let os::Pipe { input, out } = os::pipe();
let out = PipeStream::open(out);
let mut input = PipeStream::open(input);
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let mut out = out;
out.write([10]).unwrap();
p.recv(); // don't close the pipe until the other read has finished
rx.recv(); // don't close the pipe until the other read has finished
});
let mut buf = [0, ..10];
input.read(buf).unwrap();
c.send(());
tx.send(());
})
}

View File

@ -379,16 +379,16 @@ impl Process {
/// The stdin handle to the child is closed before waiting.
pub fn wait_with_output(&mut self) -> ProcessOutput {
drop(self.stdin.take());
fn read(stream: Option<io::PipeStream>) -> Port<IoResult<~[u8]>> {
let (p, c) = Chan::new();
fn read(stream: Option<io::PipeStream>) -> Receiver<IoResult<~[u8]>> {
let (tx, rx) = channel();
match stream {
Some(stream) => spawn(proc() {
let mut stream = stream;
c.send(stream.read_to_end())
tx.send(stream.read_to_end())
}),
None => c.send(Ok(~[]))
None => tx.send(Ok(~[]))
}
p
rx
}
let stdout = read(self.stdout.take());
let stderr = read(self.stderr.take());

View File

@ -20,7 +20,7 @@ definitions for a number of signals.
*/
use clone::Clone;
use comm::{Port, Chan};
use comm::{Sender, Receiver, channel};
use io;
use iter::Iterator;
use mem::drop;
@ -56,7 +56,7 @@ pub enum Signum {
WindowSizeChange = 28i,
}
/// Listener provides a port to listen for registered signals.
/// Listener provides a receiver to listen for registered signals.
///
/// Listener automatically unregisters its handles once it is out of scope.
/// However, clients can still unregister signums manually.
@ -71,7 +71,7 @@ pub enum Signum {
///
/// spawn({
/// loop {
/// match listener.port.recv() {
/// match listener.rx.recv() {
/// Interrupt => println!("Got Interrupt'ed"),
/// _ => (),
/// }
@ -82,24 +82,24 @@ pub enum Signum {
pub struct Listener {
/// A map from signums to handles to keep the handles in memory
priv handles: ~[(Signum, ~RtioSignal)],
/// chan is where all the handles send signums, which are received by
/// the clients from port.
priv chan: Chan<Signum>,
/// This is where all the handles send signums, which are received by
/// the clients from the receiver.
priv tx: Sender<Signum>,
/// Clients of Listener can `recv()` from this port. This is exposed to
/// allow selection over this port as well as manipulation of the port
/// Clients of Listener can `recv()` on this receiver. This is exposed to
/// allow selection over it as well as manipulation of the receiver
/// directly.
port: Port<Signum>,
rx: Receiver<Signum>,
}
impl Listener {
/// Creates a new listener for signals. Once created, signals are bound via
/// the `register` method (otherwise nothing will ever be received)
pub fn new() -> Listener {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
Listener {
chan: chan,
port: port,
tx: tx,
rx: rx,
handles: ~[],
}
}
@ -125,7 +125,7 @@ impl Listener {
return Ok(()); // self is already listening to signum, so succeed
}
match LocalIo::maybe_raise(|io| {
io.signal(signum, self.chan.clone())
io.signal(signum, self.tx.clone())
}) {
Ok(handle) => {
self.handles.push((signum, handle));
@ -166,7 +166,7 @@ mod test_unix {
signal.register(Interrupt).unwrap();
sigint();
timer::sleep(10);
match signal.port.recv() {
match signal.rx.recv() {
Interrupt => (),
s => fail!("Expected Interrupt, got {:?}", s),
}
@ -180,11 +180,11 @@ mod test_unix {
s2.register(Interrupt).unwrap();
sigint();
timer::sleep(10);
match s1.port.recv() {
match s1.rx.recv() {
Interrupt => (),
s => fail!("Expected Interrupt, got {:?}", s),
}
match s2.port.recv() {
match s2.rx.recv() {
Interrupt => (),
s => fail!("Expected Interrupt, got {:?}", s),
}
@ -199,7 +199,7 @@ mod test_unix {
s2.unregister(Interrupt);
sigint();
timer::sleep(10);
assert_eq!(s2.port.try_recv(), Empty);
assert_eq!(s2.rx.try_recv(), Empty);
}
}

View File

@ -388,10 +388,10 @@ mod tests {
})
iotest!(fn capture_stdout() {
use io::comm_adapters::{PortReader, ChanWriter};
use io::{ChanReader, ChanWriter};
let (p, c) = Chan::new();
let (mut r, w) = (PortReader::new(p), ChanWriter::new(c));
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
spawn(proc() {
set_stdout(~w as ~Writer);
println!("hello!");
@ -400,10 +400,10 @@ mod tests {
})
iotest!(fn capture_stderr() {
use io::comm_adapters::{PortReader, ChanWriter};
use io::{ChanReader, ChanWriter};
let (p, c) = Chan::new();
let (mut r, w) = (PortReader::new(p), ChanWriter::new(c));
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
spawn(proc() {
set_stderr(~w as ~Writer);
fail!("my special message");

View File

@ -46,9 +46,9 @@ macro_rules! iotest (
$($a)* #[test] fn green() { f() }
$($a)* #[test] fn native() {
use native;
let (p, c) = Chan::new();
native::task::spawn(proc() { c.send(f()) });
p.recv();
let (tx, rx) = channel();
native::task::spawn(proc() { tx.send(f()) });
rx.recv();
}
}
)

View File

@ -13,11 +13,11 @@
Synchronous Timers
This module exposes the functionality to create timers, block the current task,
and create ports which will receive notifications after a period of time.
and create receivers which will receive notifications after a period of time.
*/
use comm::Port;
use comm::Receiver;
use rt::rtio::{IoFactory, LocalIo, RtioTimer};
use io::IoResult;
@ -25,7 +25,7 @@ use io::IoResult;
///
/// Values of this type can be used to put the current task to sleep for a
/// period of time. Handles to this timer can also be created in the form of
/// ports which will receive notifications over time.
/// receivers which will receive notifications over time.
///
/// # Example
///
@ -83,33 +83,33 @@ impl Timer {
/// Blocks the current task for `msecs` milliseconds.
///
/// Note that this function will cause any other ports for this timer to be
/// invalidated (the other end will be closed).
/// Note that this function will cause any other receivers for this timer to
/// be invalidated (the other end will be closed).
pub fn sleep(&mut self, msecs: u64) {
self.obj.sleep(msecs);
}
/// Creates a oneshot port which will have a notification sent when `msecs`
/// milliseconds has elapsed. This does *not* block the current task, but
/// instead returns immediately.
/// Creates a oneshot receiver which will have a notification sent when
/// `msecs` milliseconds has elapsed. This does *not* block the current
/// task, but instead returns immediately.
///
/// Note that this invalidates any previous port which has been created by
/// this timer, and that the returned port will be invalidated once the
/// timer is destroyed (when it falls out of scope).
pub fn oneshot(&mut self, msecs: u64) -> Port<()> {
/// Note that this invalidates any previous receiver which has been created
/// by this timer, and that the returned receiver will be invalidated once
/// the timer is destroyed (when it falls out of scope).
pub fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
self.obj.oneshot(msecs)
}
/// Creates a port which will have a continuous stream of notifications
/// Creates a receiver which will have a continuous stream of notifications
/// being sent every `msecs` milliseconds. This does *not* block the
/// current task, but instead returns immediately. The first notification
/// will not be received immediately, but rather after `msec` milliseconds
/// have passed.
///
/// Note that this invalidates any previous port which has been created by
/// this timer, and that the returned port will be invalidated once the
/// timer is destroyed (when it falls out of scope).
pub fn periodic(&mut self, msecs: u64) -> Port<()> {
/// Note that this invalidates any previous receiver which has been created
/// by this timer, and that the returned receiver will be invalidated once
/// the timer is destroyed (when it falls out of scope).
pub fn periodic(&mut self, msecs: u64) -> Receiver<()> {
self.obj.period(msecs)
}
}
@ -133,26 +133,26 @@ mod test {
iotest!(fn oneshot_twice() {
let mut timer = Timer::new().unwrap();
let port1 = timer.oneshot(10000);
let port = timer.oneshot(1);
port.recv();
assert_eq!(port1.recv_opt(), None);
let rx1 = timer.oneshot(10000);
let rx = timer.oneshot(1);
rx.recv();
assert_eq!(rx1.recv_opt(), None);
})
iotest!(fn test_io_timer_oneshot_then_sleep() {
let mut timer = Timer::new().unwrap();
let port = timer.oneshot(100000000000);
timer.sleep(1); // this should invalidate the port
let rx = timer.oneshot(100000000000);
timer.sleep(1); // this should inalidate rx
assert_eq!(port.recv_opt(), None);
assert_eq!(rx.recv_opt(), None);
})
iotest!(fn test_io_timer_sleep_periodic() {
let mut timer = Timer::new().unwrap();
let port = timer.periodic(1);
port.recv();
port.recv();
port.recv();
let rx = timer.periodic(1);
rx.recv();
rx.recv();
rx.recv();
})
iotest!(fn test_io_timer_sleep_periodic_forget() {
@ -167,33 +167,33 @@ mod test {
iotest!(fn oneshot() {
let mut timer = Timer::new().unwrap();
let port = timer.oneshot(1);
port.recv();
assert!(port.recv_opt().is_none());
let rx = timer.oneshot(1);
rx.recv();
assert!(rx.recv_opt().is_none());
let port = timer.oneshot(1);
port.recv();
assert!(port.recv_opt().is_none());
let rx = timer.oneshot(1);
rx.recv();
assert!(rx.recv_opt().is_none());
})
iotest!(fn override() {
let mut timer = Timer::new().unwrap();
let oport = timer.oneshot(100);
let pport = timer.periodic(100);
let orx = timer.oneshot(100);
let prx = timer.periodic(100);
timer.sleep(1);
assert_eq!(oport.recv_opt(), None);
assert_eq!(pport.recv_opt(), None);
assert_eq!(orx.recv_opt(), None);
assert_eq!(prx.recv_opt(), None);
timer.oneshot(1).recv();
})
iotest!(fn period() {
let mut timer = Timer::new().unwrap();
let port = timer.periodic(1);
port.recv();
port.recv();
let port2 = timer.periodic(1);
port2.recv();
port2.recv();
let rx = timer.periodic(1);
rx.recv();
rx.recv();
let rx2 = timer.periodic(1);
rx2.recv();
rx2.recv();
})
iotest!(fn sleep() {
@ -204,13 +204,13 @@ mod test {
iotest!(fn oneshot_fail() {
let mut timer = Timer::new().unwrap();
let _port = timer.oneshot(1);
let _rx = timer.oneshot(1);
fail!();
} #[should_fail])
iotest!(fn period_fail() {
let mut timer = Timer::new().unwrap();
let _port = timer.periodic(1);
let _rx = timer.periodic(1);
fail!();
} #[should_fail])
@ -222,10 +222,10 @@ mod test {
iotest!(fn closing_channel_during_drop_doesnt_kill_everything() {
// see issue #10375
let mut timer = Timer::new().unwrap();
let timer_port = timer.periodic(1000);
let timer_rx = timer.periodic(1000);
spawn(proc() {
timer_port.recv_opt();
timer_rx.recv_opt();
});
// when we drop the TimerWatcher we're going to destroy the channel,
@ -235,10 +235,10 @@ mod test {
iotest!(fn reset_doesnt_switch_tasks() {
// similar test to the one above.
let mut timer = Timer::new().unwrap();
let timer_port = timer.periodic(1000);
let timer_rx = timer.periodic(1000);
spawn(proc() {
timer_port.recv_opt();
timer_rx.recv_opt();
});
timer.oneshot(1);
@ -247,29 +247,29 @@ mod test {
iotest!(fn reset_doesnt_switch_tasks2() {
// similar test to the one above.
let mut timer = Timer::new().unwrap();
let timer_port = timer.periodic(1000);
let timer_rx = timer.periodic(1000);
spawn(proc() {
timer_port.recv_opt();
timer_rx.recv_opt();
});
timer.sleep(1);
})
iotest!(fn sender_goes_away_oneshot() {
let port = {
let rx = {
let mut timer = Timer::new().unwrap();
timer.oneshot(1000)
};
assert_eq!(port.recv_opt(), None);
assert_eq!(rx.recv_opt(), None);
})
iotest!(fn sender_goes_away_period() {
let port = {
let rx = {
let mut timer = Timer::new().unwrap();
timer.periodic(1000)
};
assert_eq!(port.recv_opt(), None);
assert_eq!(rx.recv_opt(), None);
})
iotest!(fn receiver_goes_away_oneshot() {

View File

@ -387,17 +387,17 @@ macro_rules! vec(
/// # Example
///
/// ```
/// let (p1, c1) = Chan::new();
/// let (p2, c2) = Chan::new();
/// let (tx1, rx1) = channel();
/// let (tx2, rx2) = channel();
/// # fn long_running_task() {}
/// # fn calculate_the_answer() -> int { 42 }
///
/// spawn(proc() { long_running_task(); c1.send(()) });
/// spawn(proc() { c2.send(calculate_the_answer()) });
/// spawn(proc() { long_running_task(); tx1.send(()) });
/// spawn(proc() { tx2.send(calculate_the_answer()) });
///
/// select! (
/// () = p1.recv() => println!("the long running task finished first"),
/// answer = p2.recv() => {
/// () = rx1.recv() => println!("the long running task finished first"),
/// answer = rx2.recv() => {
/// println!("the answer was: {}", answer);
/// }
/// )
@ -408,16 +408,16 @@ macro_rules! vec(
#[experimental]
macro_rules! select {
(
$($name:pat = $port:ident.$meth:ident() => $code:expr),+
$($name:pat = $rx:ident.$meth:ident() => $code:expr),+
) => ({
use std::comm::Select;
let sel = Select::new();
$( let mut $port = sel.handle(&$port); )+
$( let mut $rx = sel.handle(&$rx); )+
unsafe {
$( $port.add(); )+
$( $rx.add(); )+
}
let ret = sel.wait();
$( if ret == $port.id() { let $name = $port.$meth(); $code } else )+
$( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
{ unreachable!() }
})
}

View File

@ -61,7 +61,7 @@ pub use vec::{MutableVector, MutableTotalOrdVector};
pub use vec::{Vector, VectorVector, CloneableVector, ImmutableVector};
// Reexported runtime types
pub use comm::{Port, Chan};
pub use comm::{channel, Sender, Receiver};
pub use task::spawn;
// Reexported statics

View File

@ -10,7 +10,7 @@
use c_str::CString;
use cast;
use comm::{Chan, Port};
use comm::{Sender, Receiver};
use libc::c_int;
use libc;
use ops::Drop;
@ -183,7 +183,7 @@ pub trait IoFactory {
fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError>;
fn tty_open(&mut self, fd: c_int, readable: bool)
-> Result<~RtioTTY, IoError>;
fn signal(&mut self, signal: Signum, channel: Chan<Signum>)
fn signal(&mut self, signal: Signum, channel: Sender<Signum>)
-> Result<~RtioSignal, IoError>;
}
@ -233,8 +233,8 @@ pub trait RtioUdpSocket : RtioSocket {
pub trait RtioTimer {
fn sleep(&mut self, msecs: u64);
fn oneshot(&mut self, msecs: u64) -> Port<()>;
fn period(&mut self, msecs: u64) -> Port<()>;
fn oneshot(&mut self, msecs: u64) -> Receiver<()>;
fn period(&mut self, msecs: u64) -> Receiver<()>;
}
pub trait RtioFileStream {

View File

@ -17,7 +17,7 @@ use any::AnyOwnExt;
use cast;
use cleanup;
use clone::Clone;
use comm::Chan;
use comm::Sender;
use io::Writer;
use iter::{Iterator, Take};
use local_data;
@ -73,7 +73,7 @@ pub enum DeathAction {
/// until all its watched children exit before collecting the status.
Execute(proc(TaskResult)),
/// A channel to send the result of the task on when the task exits
SendMessage(Chan<TaskResult>),
SendMessage(Sender<TaskResult>),
}
/// Per-task state related to task death, killing, failure, etc.
@ -450,16 +450,16 @@ mod test {
#[test]
fn comm_stream() {
let (port, chan) = Chan::new();
chan.send(10);
assert!(port.recv() == 10);
let (tx, rx) = channel();
tx.send(10);
assert!(rx.recv() == 10);
}
#[test]
fn comm_shared_chan() {
let (port, chan) = Chan::new();
chan.send(10);
assert!(port.recv() == 10);
let (tx, rx) = channel();
tx.send(10);
assert!(rx.recv() == 10);
}
#[test]

View File

@ -172,24 +172,24 @@ mod tests {
let nmsgs = 1000u;
let mut q = Queue::with_capacity(nthreads*nmsgs);
assert_eq!(None, q.pop());
let (port, chan) = Chan::new();
let (tx, rx) = channel();
for _ in range(0, nthreads) {
let q = q.clone();
let chan = chan.clone();
let tx = tx.clone();
native::task::spawn(proc() {
let mut q = q;
for i in range(0, nmsgs) {
assert!(q.push(i));
}
chan.send(());
tx.send(());
});
}
let mut completion_ports = ~[];
let mut completion_rxs = ~[];
for _ in range(0, nthreads) {
let (completion_port, completion_chan) = Chan::new();
completion_ports.push(completion_port);
let (tx, rx) = channel();
completion_rxs.push(rx);
let q = q.clone();
native::task::spawn(proc() {
let mut q = q;
@ -203,15 +203,15 @@ mod tests {
}
}
}
completion_chan.send(i);
tx.send(i);
});
}
for completion_port in completion_ports.mut_iter() {
assert_eq!(nmsgs, completion_port.recv());
for rx in completion_rxs.mut_iter() {
assert_eq!(nmsgs, rx.recv());
}
for _ in range(0, nthreads) {
port.recv();
rx.recv();
}
}
}

View File

@ -176,17 +176,17 @@ mod tests {
Empty => {}
Inconsistent | Data(..) => fail!()
}
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let q = UnsafeArc::new(q);
for _ in range(0, nthreads) {
let chan = chan.clone();
let tx = tx.clone();
let q = q.clone();
native::task::spawn(proc() {
for i in range(0, nmsgs) {
unsafe { (*q.get()).push(i); }
}
chan.send(());
tx.send(());
});
}
@ -197,9 +197,9 @@ mod tests {
Data(_) => { i += 1 }
}
}
drop(chan);
drop(tx);
for _ in range(0, nthreads) {
port.recv();
rx.recv();
}
}
}

View File

@ -273,7 +273,7 @@ mod test {
fn stress_bound(bound: uint) {
let (a, b) = UnsafeArc::new2(Queue::new(bound));
let (port, chan) = Chan::new();
let (tx, rx) = channel();
native::task::spawn(proc() {
for _ in range(0, 100000) {
loop {
@ -284,12 +284,12 @@ mod test {
}
}
}
chan.send(());
tx.send(());
});
for _ in range(0, 100000) {
unsafe { (*a.get()).push(1); }
}
port.recv();
rx.recv();
}
}
}

View File

@ -11,26 +11,25 @@
/*!
* Utilities for managing and scheduling tasks
*
* An executing Rust program consists of a tree of tasks, each with their own
* stack, and sole ownership of their allocated heap data. Tasks communicate
* with each other using ports and channels (see std::comm for more info
* about how communication works).
* An executing Rust program consists of a collection of tasks, each with their
* own stack, and sole ownership of their allocated heap data. Tasks communicate
* with each other using channels (see `std::comm` for more info about how
* communication works).
*
* Failure in one task does not propagate to any others (not to parent, not to child).
* Failure propagation is instead handled by using Chan.send() and Port.recv(), which
* will fail if the other end has hung up already.
* Failure in one task does not propagate to any others (not to parent, not to
* child). Failure propagation is instead handled by using the channel send()
* and recv() methods which will fail if the other end has hung up already.
*
* Task Scheduling:
*
* By default, every task is created in the same scheduler as its parent, where it
* is scheduled cooperatively with all other tasks in that scheduler. Some specialized
* applications may want more control over their scheduling, in which case they can be
* spawned into a new scheduler with the specific properties required. See TaskBuilder's
* documentation bellow for more information.
* By default, every task is created with the same "flavor" as the calling task.
* This flavor refers to the scheduling mode, with two possibilities currently
* being 1:1 and M:N modes. Green (M:N) tasks are cooperatively scheduled and
* native (1:1) tasks are scheduled by the OS kernel.
*
* # Example
*
* ```
* ```rust
* spawn(proc() {
* println!("Hello, World!");
* })
@ -38,7 +37,7 @@
*/
use any::Any;
use comm::{Chan, Port};
use comm::{Sender, Receiver, channel};
use io::Writer;
use kinds::{Send, marker};
use logging::Logger;
@ -62,7 +61,7 @@ pub type TaskResult = Result<(), ~Any>;
/// Task configuration options
pub struct TaskOpts {
/// Enable lifecycle notifications on the given channel
notify_chan: Option<Chan<TaskResult>>,
notify_chan: Option<Sender<TaskResult>>,
/// A name for the task-to-be, for identification in failure messages
name: Option<SendStr>,
/// The size of the stack for the spawned task
@ -116,7 +115,7 @@ impl TaskBuilder {
///
/// # Failure
/// Fails if a future_result was already set for this task.
pub fn future_result(&mut self) -> Port<TaskResult> {
pub fn future_result(&mut self) -> Receiver<TaskResult> {
// FIXME (#3725): Once linked failure and notification are
// handled in the library, I can imagine implementing this by just
// registering an arbitrary number of task::on_exit handlers and
@ -127,12 +126,12 @@ impl TaskBuilder {
}
// Construct the future and give it to the caller.
let (notify_pipe_po, notify_pipe_ch) = Chan::new();
let (tx, rx) = channel();
// Reconfigure self to use a notify channel.
self.opts.notify_chan = Some(notify_pipe_ch);
self.opts.notify_chan = Some(tx);
notify_pipe_po
rx
}
/// Name the task-to-be. Currently the name is used for identification
@ -204,16 +203,16 @@ impl TaskBuilder {
* Fails if a future_result was already set for this task.
*/
pub fn try<T:Send>(mut self, f: proc() -> T) -> Result<T, ~Any> {
let (po, ch) = Chan::new();
let (tx, rx) = channel();
let result = self.future_result();
self.spawn(proc() {
ch.send(f());
tx.send(f());
});
match result.recv() {
Ok(()) => Ok(po.recv()),
Ok(()) => Ok(rx.recv()),
Err(cause) => Err(cause)
}
}
@ -340,25 +339,24 @@ fn test_send_named_task() {
#[test]
fn test_run_basic() {
let (po, ch) = Chan::new();
let (tx, rx) = channel();
task().spawn(proc() {
ch.send(());
tx.send(());
});
po.recv();
rx.recv();
}
#[test]
fn test_with_wrapper() {
let (po, ch) = Chan::new();
let (tx, rx) = channel();
task().with_wrapper(proc(body) {
let ch = ch;
let result: proc() = proc() {
body();
ch.send(());
tx.send(());
};
result
}).spawn(proc() { });
po.recv();
rx.recv();
}
#[test]
@ -407,50 +405,49 @@ fn test_try_fail() {
fn test_spawn_sched() {
use clone::Clone;
let (po, ch) = Chan::new();
let (tx, rx) = channel();
fn f(i: int, ch: Chan<()>) {
let ch = ch.clone();
fn f(i: int, tx: Sender<()>) {
let tx = tx.clone();
spawn(proc() {
if i == 0 {
ch.send(());
tx.send(());
} else {
f(i - 1, ch);
f(i - 1, tx);
}
});
}
f(10, ch);
po.recv();
f(10, tx);
rx.recv();
}
#[test]
fn test_spawn_sched_childs_on_default_sched() {
let (po, ch) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let ch = ch;
spawn(proc() {
ch.send(());
tx.send(());
});
});
po.recv();
rx.recv();
}
#[cfg(test)]
fn avoid_copying_the_body(spawnfn: |v: proc()|) {
let (p, ch) = Chan::<uint>::new();
let (tx, rx) = channel::<uint>();
let x = ~1;
let x_in_parent = (&*x) as *int as uint;
spawnfn(proc() {
let x_in_child = (&*x) as *int as uint;
ch.send(x_in_child);
tx.send(x_in_child);
});
let x_in_child = p.recv();
let x_in_child = rx.recv();
assert_eq!(x_in_parent, x_in_child);
}

View File

@ -124,14 +124,14 @@ mod tests {
for _ in range(0u, num_tasks) {
let total = total.clone();
let (port, chan) = Chan::new();
futures.push(port);
let (tx, rx) = channel();
futures.push(rx);
task::spawn(proc() {
for _ in range(0u, count) {
total.with(|count| **count += 1);
}
chan.send(());
tx.send(());
});
};

View File

@ -20,19 +20,20 @@
* ```rust
* extern crate sync;
* extern crate rand;
* use sync::Arc;
*
* use std::vec;
* use sync::Arc;
*
* fn main() {
* let numbers = vec::from_fn(100, |i| (i as f32) * rand::random());
* let shared_numbers = Arc::new(numbers);
*
* for _ in range(0, 10) {
* let (port, chan) = Chan::new();
* chan.send(shared_numbers.clone());
* let (tx, rx) = channel();
* tx.send(shared_numbers.clone());
*
* spawn(proc() {
* let shared_numbers = port.recv();
* let shared_numbers = rx.recv();
* let local_numbers = shared_numbers.get();
*
* // Work with the local numbers
@ -582,16 +583,16 @@ mod tests {
let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arc_v = Arc::new(v);
let (p, c) = Chan::new();
let (tx, rx) = channel();
task::spawn(proc() {
let arc_v: Arc<~[int]> = p.recv();
let arc_v: Arc<~[int]> = rx.recv();
let v = arc_v.get().clone();
assert_eq!(v[3], 4);
});
c.send(arc_v.clone());
tx.send(arc_v.clone());
assert_eq!(arc_v.get()[2], 3);
assert_eq!(arc_v.get()[4], 5);
@ -603,10 +604,10 @@ mod tests {
fn test_mutex_arc_condvar() {
let arc = ~MutexArc::new(false);
let arc2 = ~arc.clone();
let (p,c) = Chan::new();
let (tx, rx) = channel();
task::spawn(proc() {
// wait until parent gets in
p.recv();
rx.recv();
arc2.access_cond(|state, cond| {
*state = true;
cond.signal();
@ -614,7 +615,7 @@ mod tests {
});
arc.access_cond(|state, cond| {
c.send(());
tx.send(());
assert!(!*state);
while !*state {
cond.wait();
@ -626,10 +627,10 @@ mod tests {
fn test_arc_condvar_poison() {
let arc = ~MutexArc::new(1);
let arc2 = ~arc.clone();
let (p, c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let _ = p.recv();
let _ = rx.recv();
arc2.access_cond(|one, cond| {
cond.signal();
// Parent should fail when it wakes up.
@ -638,7 +639,7 @@ mod tests {
});
arc.access_cond(|one, cond| {
c.send(());
tx.send(());
while *one == 1 {
cond.wait();
}
@ -781,7 +782,7 @@ mod tests {
fn test_rw_arc() {
let arc = RWArc::new(0);
let arc2 = arc.clone();
let (p, c) = Chan::new();
let (tx, rx) = channel();
task::spawn(proc() {
arc2.write(|num| {
@ -791,7 +792,7 @@ mod tests {
task::deschedule();
*num = tmp + 1;
}
c.send(());
tx.send(());
})
});
@ -814,7 +815,7 @@ mod tests {
}
// Wait for writer to finish
p.recv();
rx.recv();
arc.read(|num| {
assert_eq!(*num, 10);
})
@ -852,42 +853,42 @@ mod tests {
// Reader tasks
let mut reader_convos = ~[];
for _ in range(0, 10) {
let ((rp1, rc1), (rp2, rc2)) = (Chan::new(), Chan::new());
reader_convos.push((rc1, rp2));
let ((tx1, rx1), (tx2, rx2)) = (channel(), channel());
reader_convos.push((tx1, rx2));
let arcn = arc.clone();
task::spawn(proc() {
rp1.recv(); // wait for downgrader to give go-ahead
rx1.recv(); // wait for downgrader to give go-ahead
arcn.read(|state| {
assert_eq!(*state, 31337);
rc2.send(());
tx2.send(());
})
});
}
// Writer task
let arc2 = arc.clone();
let ((wp1, wc1), (wp2, wc2)) = (Chan::new(), Chan::new());
let ((tx1, rx1), (tx2, rx2)) = (channel(), channel());
task::spawn(proc() {
wp1.recv();
rx1.recv();
arc2.write_cond(|state, cond| {
assert_eq!(*state, 0);
*state = 42;
cond.signal();
});
wp1.recv();
rx1.recv();
arc2.write(|state| {
// This shouldn't happen until after the downgrade read
// section, and all other readers, finish.
assert_eq!(*state, 31337);
*state = 42;
});
wc2.send(());
tx2.send(());
});
// Downgrader (us)
arc.write_downgrade(|mut write_mode| {
write_mode.write_cond(|state, cond| {
wc1.send(()); // send to another writer who will wake us up
tx1.send(()); // send to another writer who will wake us up
while *state == 0 {
cond.wait();
}
@ -904,12 +905,12 @@ mod tests {
for &(_, ref mut rp) in reader_convos.mut_iter() {
rp.recv()
}
wc1.send(()); // tell writer to try again
tx1.send(()); // tell writer to try again
assert_eq!(*state, 31337);
});
});
wp2.recv(); // complete handshake with writer
rx2.recv(); // complete handshake with writer
}
#[cfg(test)]
fn test_rw_write_cond_downgrade_read_race_helper() {
@ -923,13 +924,13 @@ mod tests {
// "blk(&ArcCondvar { order: opt_lock, ..*cond })"
// with just "blk(cond)".
let x = RWArc::new(true);
let (wp, wc) = Chan::new();
let (tx, rx) = channel();
// writer task
let xw = x.clone();
task::spawn(proc() {
xw.write_cond(|state, c| {
wc.send(()); // tell downgrader it's ok to go
tx.send(()); // tell downgrader it's ok to go
c.wait();
// The core of the test is here: the condvar reacquire path
// must involve order_lock, so that it cannot race with a reader
@ -938,7 +939,7 @@ mod tests {
})
});
wp.recv(); // wait for writer to get in
rx.recv(); // wait for writer to get in
x.write_downgrade(|mut write_mode| {
write_mode.write_cond(|state, c| {
@ -948,12 +949,12 @@ mod tests {
});
// make a reader task to trigger the "reader cloud lock" handoff
let xr = x.clone();
let (rp, rc) = Chan::new();
let (tx, rx) = channel();
task::spawn(proc() {
rc.send(());
tx.send(());
xr.read(|_state| { })
});
rp.recv(); // wait for reader task to exist
rx.recv(); // wait for reader task to exist
let read_mode = x.downgrade(write_mode);
read_mode.read(|state| {

View File

@ -20,44 +20,45 @@ use std::comm;
/// An extension of `pipes::stream` that allows both sending and receiving.
pub struct DuplexStream<T, U> {
priv chan: Chan<T>,
priv port: Port<U>,
priv tx: Sender<T>,
priv rx: Receiver<U>,
}
/// Creates a bidirectional stream.
pub fn duplex<T: Send, U: Send>() -> (DuplexStream<T, U>, DuplexStream<U, T>) {
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
(DuplexStream { tx: tx1, rx: rx2 },
DuplexStream { tx: tx2, rx: rx1 })
}
// Allow these methods to be used without import:
impl<T:Send,U:Send> DuplexStream<T, U> {
/// Creates a bidirectional stream.
pub fn new() -> (DuplexStream<T, U>, DuplexStream<U, T>) {
let (p1, c2) = Chan::new();
let (p2, c1) = Chan::new();
(DuplexStream { chan: c1, port: p1 },
DuplexStream { chan: c2, port: p2 })
}
pub fn send(&self, x: T) {
self.chan.send(x)
self.tx.send(x)
}
pub fn try_send(&self, x: T) -> bool {
self.chan.try_send(x)
self.tx.try_send(x)
}
pub fn recv(&self) -> U {
self.port.recv()
self.rx.recv()
}
pub fn try_recv(&self) -> comm::TryRecvResult<U> {
self.port.try_recv()
self.rx.try_recv()
}
pub fn recv_opt(&self) -> Option<U> {
self.port.recv_opt()
self.rx.recv_opt()
}
}
/// An extension of `pipes::stream` that provides synchronous message sending.
pub struct SyncChan<T> { priv duplex_stream: DuplexStream<T, ()> }
pub struct SyncSender<T> { priv duplex_stream: DuplexStream<T, ()> }
/// An extension of `pipes::stream` that acknowledges each message received.
pub struct SyncPort<T> { priv duplex_stream: DuplexStream<(), T> }
pub struct SyncReceiver<T> { priv duplex_stream: DuplexStream<(), T> }
impl<T: Send> SyncChan<T> {
impl<T: Send> SyncSender<T> {
pub fn send(&self, val: T) {
assert!(self.try_send(val), "SyncChan.send: receiving port closed");
assert!(self.try_send(val), "SyncSender.send: receiving port closed");
}
/// Sends a message, or report if the receiver has closed the connection
@ -67,9 +68,9 @@ impl<T: Send> SyncChan<T> {
}
}
impl<T: Send> SyncPort<T> {
impl<T: Send> SyncReceiver<T> {
pub fn recv(&self) -> T {
self.recv_opt().expect("SyncPort.recv: sending channel closed")
self.recv_opt().expect("SyncReceiver.recv: sending channel closed")
}
pub fn recv_opt(&self) -> Option<T> {
@ -89,20 +90,20 @@ impl<T: Send> SyncPort<T> {
/// Creates a stream whose channel, upon sending a message, blocks until the
/// message is received.
pub fn rendezvous<T: Send>() -> (SyncPort<T>, SyncChan<T>) {
let (chan_stream, port_stream) = DuplexStream::new();
(SyncPort { duplex_stream: port_stream },
SyncChan { duplex_stream: chan_stream })
pub fn rendezvous<T: Send>() -> (SyncReceiver<T>, SyncSender<T>) {
let (chan_stream, port_stream) = duplex();
(SyncReceiver { duplex_stream: port_stream },
SyncSender { duplex_stream: chan_stream })
}
#[cfg(test)]
mod test {
use comm::{DuplexStream, rendezvous};
use comm::{duplex, rendezvous};
#[test]
pub fn DuplexStream1() {
let (left, right) = DuplexStream::new();
let (left, right) = duplex();
left.send(~"abc");
right.send(123);

View File

@ -104,7 +104,7 @@ impl<A> Future<A> {
}
impl<A:Send> Future<A> {
pub fn from_port(port: Port<A>) -> Future<A> {
pub fn from_receiver(rx: Receiver<A>) -> Future<A> {
/*!
* Create a future from a port
*
@ -113,7 +113,7 @@ impl<A:Send> Future<A> {
*/
Future::from_fn(proc() {
port.recv()
rx.recv()
})
}
@ -125,13 +125,13 @@ impl<A:Send> Future<A> {
* value of the future.
*/
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
chan.send(blk());
tx.send(blk());
});
Future::from_port(port)
Future::from_receiver(rx)
}
}
@ -148,10 +148,10 @@ mod test {
}
#[test]
fn test_from_port() {
let (po, ch) = Chan::new();
ch.send(~"whale");
let mut f = Future::from_port(po);
fn test_from_receiver() {
let (tx, rx) = channel();
tx.send(~"whale");
let mut f = Future::from_receiver(rx);
assert_eq!(f.get(), ~"whale");
}

View File

@ -19,8 +19,8 @@
pub use arc::{Arc, MutexArc, RWArc, RWWriteMode, RWReadMode, ArcCondvar, CowArc};
pub use sync::{Mutex, RWLock, Condvar, Semaphore, RWLockWriteMode,
RWLockReadMode, Barrier, one, mutex};
pub use comm::{DuplexStream, SyncChan, SyncPort, rendezvous};
RWLockReadMode, Barrier, one, mutex};
pub use comm::{DuplexStream, SyncSender, SyncReceiver, rendezvous, duplex};
pub use task_pool::TaskPool;
pub use future::Future;

View File

@ -37,17 +37,17 @@ mod mpsc_intrusive;
// Each waiting task receives on one of these.
#[doc(hidden)]
type WaitEnd = Port<()>;
type WaitEnd = Receiver<()>;
#[doc(hidden)]
type SignalEnd = Chan<()>;
type SignalEnd = Sender<()>;
// A doubly-ended queue of waiting tasks.
#[doc(hidden)]
struct WaitQueue { head: Port<SignalEnd>,
tail: Chan<SignalEnd> }
struct WaitQueue { head: Receiver<SignalEnd>,
tail: Sender<SignalEnd> }
impl WaitQueue {
fn new() -> WaitQueue {
let (block_head, block_tail) = Chan::new();
let (block_tail, block_head) = channel();
WaitQueue { head: block_head, tail: block_tail }
}
@ -83,7 +83,7 @@ impl WaitQueue {
}
fn wait_end(&self) -> WaitEnd {
let (wait_end, signal_end) = Chan::new();
let (signal_end, wait_end) = channel();
assert!(self.tail.try_send(signal_end));
wait_end
}
@ -797,28 +797,28 @@ mod tests {
#[test]
fn test_sem_as_cvar() {
/* Child waits and parent signals */
let (p, c) = Chan::new();
let (tx, rx) = channel();
let s = Semaphore::new(0);
let s2 = s.clone();
task::spawn(proc() {
s2.acquire();
c.send(());
tx.send(());
});
for _ in range(0, 5) { task::deschedule(); }
s.release();
let _ = p.recv();
let _ = rx.recv();
/* Parent waits and child signals */
let (p, c) = Chan::new();
let (tx, rx) = channel();
let s = Semaphore::new(0);
let s2 = s.clone();
task::spawn(proc() {
for _ in range(0, 5) { task::deschedule(); }
s2.release();
let _ = p.recv();
let _ = rx.recv();
});
s.acquire();
c.send(());
tx.send(());
}
#[test]
fn test_sem_multi_resource() {
@ -826,17 +826,17 @@ mod tests {
// time, and shake hands.
let s = Semaphore::new(2);
let s2 = s.clone();
let (p1,c1) = Chan::new();
let (p2,c2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
task::spawn(proc() {
s2.access(|| {
let _ = p2.recv();
c1.send(());
let _ = rx2.recv();
tx1.send(());
})
});
s.access(|| {
c2.send(());
let _ = p1.recv();
tx2.send(());
let _ = rx1.recv();
})
}
#[test]
@ -845,19 +845,19 @@ mod tests {
// When one blocks, it should schedule the other one.
let s = Semaphore::new(1);
let s2 = s.clone();
let (p, c) = Chan::new();
let mut child_data = Some((s2, c));
let (tx, rx) = channel();
let mut child_data = Some((s2, tx));
s.access(|| {
let (s2, c) = child_data.take_unwrap();
let (s2, tx) = child_data.take_unwrap();
task::spawn(proc() {
c.send(());
tx.send(());
s2.access(|| { });
c.send(());
tx.send(());
});
let _ = p.recv(); // wait for child to come alive
let _ = rx.recv(); // wait for child to come alive
for _ in range(0, 5) { task::deschedule(); } // let the child contend
});
let _ = p.recv(); // wait for child to be done
let _ = rx.recv(); // wait for child to be done
}
/************************************************************************
* Mutex tests
@ -866,7 +866,7 @@ mod tests {
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) = Chan::new();
let (tx, rx) = channel();
let m = Mutex::new();
let m2 = m.clone();
let mut sharedstate = ~0;
@ -876,12 +876,12 @@ mod tests {
let sharedstate: &mut int =
unsafe { cast::transmute(ptr) };
access_shared(sharedstate, &m2, 10);
c.send(());
tx.send(());
});
}
{
access_shared(sharedstate, &m, 10);
let _ = p.recv();
let _ = rx.recv();
assert_eq!(*sharedstate, 20);
}
@ -912,48 +912,48 @@ mod tests {
cond.wait();
});
// Parent wakes up child
let (port,chan) = Chan::new();
let (tx, rx) = channel();
let m3 = m.clone();
task::spawn(proc() {
m3.lock_cond(|cond| {
chan.send(());
tx.send(());
cond.wait();
chan.send(());
tx.send(());
})
});
let _ = port.recv(); // Wait until child gets in the mutex
let _ = rx.recv(); // Wait until child gets in the mutex
m.lock_cond(|cond| {
let woken = cond.signal();
assert!(woken);
});
let _ = port.recv(); // Wait until child wakes up
let _ = rx.recv(); // Wait until child wakes up
}
#[cfg(test)]
fn test_mutex_cond_broadcast_helper(num_waiters: uint) {
let m = Mutex::new();
let mut ports = ~[];
let mut rxs = ~[];
for _ in range(0, num_waiters) {
let mi = m.clone();
let (port, chan) = Chan::new();
ports.push(port);
let (tx, rx) = channel();
rxs.push(rx);
task::spawn(proc() {
mi.lock_cond(|cond| {
chan.send(());
tx.send(());
cond.wait();
chan.send(());
tx.send(());
})
});
}
// wait until all children get in the mutex
for port in ports.mut_iter() { let _ = port.recv(); }
for rx in rxs.mut_iter() { let _ = rx.recv(); }
m.lock_cond(|cond| {
let num_woken = cond.broadcast();
assert_eq!(num_woken, num_waiters);
});
// wait until all children wake up
for port in ports.mut_iter() { let _ = port.recv(); }
for rx in rxs.mut_iter() { let _ = rx.recv(); }
}
#[test]
fn test_mutex_cond_broadcast() {
@ -991,81 +991,6 @@ mod tests {
// child task must have finished by the time try returns
m.lock(|| { })
}
#[ignore(reason = "linked failure")]
#[test]
fn test_mutex_killed_cond() {
use std::any::Any;
// 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 result: result::Result<(), ~Any> = task::try(proc() {
let (p, c) = Chan::new();
task::spawn(proc() { // linked
let _ = p.recv(); // wait for sibling to get in the mutex
task::deschedule();
fail!();
});
m2.lock_cond(|cond| {
c.send(()); // tell sibling go ahead
cond.wait(); // block forever
})
});
assert!(result.is_err());
// child task must have finished by the time try returns
m.lock_cond(|cond| {
let woken = cond.signal();
assert!(!woken);
})
}
#[ignore(reason = "linked failure")]
#[test]
fn test_mutex_killed_broadcast() {
use std::any::Any;
use std::unstable::finally::Finally;
let m = Mutex::new();
let m2 = m.clone();
let (p, c) = Chan::new();
let result: result::Result<(), ~Any> = task::try(proc() {
let mut sibling_convos = ~[];
for _ in range(0, 2) {
let (p, c) = Chan::new();
sibling_convos.push(p);
let mi = m2.clone();
// spawn sibling task
task::spawn(proc() { // linked
mi.lock_cond(|cond| {
c.send(()); // tell sibling to go ahead
(|| {
cond.wait(); // block forever
}).finally(|| {
error!("task unwinding and sending");
c.send(());
error!("task unwinding and done sending");
})
})
});
}
for p in sibling_convos.mut_iter() {
let _ = p.recv(); // wait for sibling to get in the mutex
}
m2.lock(|| { });
c.send(sibling_convos); // let parent wait on all children
fail!();
});
assert!(result.is_err());
// child task must have finished by the time try returns
let mut r = p.recv();
for p in r.mut_iter() { p.recv(); } // wait on all its siblings
m.lock_cond(|cond| {
let woken = cond.broadcast();
assert_eq!(woken, 0);
})
}
#[test]
fn test_mutex_cond_signal_on_0() {
// Tests that signal_on(0) is equivalent to signal().
@ -1081,28 +1006,6 @@ mod tests {
})
}
#[test]
#[ignore(reason = "linked failure?")]
fn test_mutex_different_conds() {
let result = task::try(proc() {
let m = Mutex::new_with_condvars(2);
let m2 = m.clone();
let (p, c) = Chan::new();
task::spawn(proc() {
m2.lock_cond(|cond| {
c.send(());
cond.wait_on(1);
})
});
let _ = p.recv();
m.lock_cond(|cond| {
if !cond.signal_on(0) {
fail!(); // success; punt sibling awake.
}
})
});
assert!(result.is_err());
}
#[test]
fn test_mutex_no_condvars() {
let result = task::try(proc() {
let m = Mutex::new_with_condvars(0);
@ -1143,11 +1046,11 @@ mod tests {
}
#[cfg(test)]
fn test_rwlock_exclusion(x: &RWLock,
mode1: RWLockMode,
mode2: RWLockMode) {
mode1: RWLockMode,
mode2: RWLockMode) {
// Test mutual exclusion between readers and writers. Just like the
// mutex mutual exclusion test, a ways above.
let (p, c) = Chan::new();
let (tx, rx) = channel();
let x2 = x.clone();
let mut sharedstate = ~0;
{
@ -1156,12 +1059,12 @@ mod tests {
let sharedstate: &mut int =
unsafe { cast::transmute(ptr) };
access_shared(sharedstate, &x2, mode1, 10);
c.send(());
tx.send(());
});
}
{
access_shared(sharedstate, x, mode2, 10);
let _ = p.recv();
let _ = rx.recv();
assert_eq!(*sharedstate, 20);
}
@ -1198,29 +1101,29 @@ mod tests {
make_mode2_go_first: bool) {
// Much like sem_multi_resource.
let x2 = x.clone();
let (p1, c1) = Chan::new();
let (p2, c2) = Chan::new();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
task::spawn(proc() {
if !make_mode2_go_first {
let _ = p2.recv(); // parent sends to us once it locks, or ...
let _ = rx2.recv(); // parent sends to us once it locks, or ...
}
lock_rwlock_in_mode(&x2, mode2, || {
if make_mode2_go_first {
c1.send(()); // ... we send to it once we lock
tx1.send(()); // ... we send to it once we lock
}
let _ = p2.recv();
c1.send(());
let _ = rx2.recv();
tx1.send(());
})
});
if make_mode2_go_first {
let _ = p1.recv(); // child sends to us once it locks, or ...
let _ = rx1.recv(); // child sends to us once it locks, or ...
}
lock_rwlock_in_mode(x, mode1, || {
if !make_mode2_go_first {
c2.send(()); // ... we send to it once we lock
tx2.send(()); // ... we send to it once we lock
}
c2.send(());
let _ = p1.recv();
tx2.send(());
let _ = rx1.recv();
})
}
#[test]
@ -1264,22 +1167,22 @@ mod tests {
cond.wait();
});
// Parent wakes up child
let (port, chan) = Chan::new();
let (tx, rx) = channel();
let x3 = x.clone();
task::spawn(proc() {
x3.write_cond(|cond| {
chan.send(());
tx.send(());
cond.wait();
chan.send(());
tx.send(());
})
});
let _ = port.recv(); // Wait until child gets in the rwlock
let _ = rx.recv(); // Wait until child gets in the rwlock
x.read(|| { }); // Must be able to get in as a reader in the meantime
x.write_cond(|cond| { // Or as another writer
let woken = cond.signal();
assert!(woken);
});
let _ = port.recv(); // Wait until child wakes up
let _ = rx.recv(); // Wait until child wakes up
x.read(|| { }); // Just for good measure
}
#[cfg(test)]
@ -1297,29 +1200,29 @@ mod tests {
}
}
let x = RWLock::new();
let mut ports = ~[];
let mut rxs = ~[];
for _ in range(0, num_waiters) {
let xi = x.clone();
let (port, chan) = Chan::new();
ports.push(port);
let (tx, rx) = channel();
rxs.push(rx);
task::spawn(proc() {
lock_cond(&xi, dg1, |cond| {
chan.send(());
tx.send(());
cond.wait();
chan.send(());
tx.send(());
})
});
}
// wait until all children get in the mutex
for port in ports.mut_iter() { let _ = port.recv(); }
for rx in rxs.mut_iter() { let _ = rx.recv(); }
lock_cond(&x, dg2, |cond| {
let num_woken = cond.broadcast();
assert_eq!(num_woken, num_waiters);
});
// wait until all children wake up
for port in ports.mut_iter() { let _ = port.recv(); }
for rx in rxs.mut_iter() { let _ = rx.recv(); }
}
#[test]
fn test_rwlock_cond_broadcast() {
@ -1400,20 +1303,20 @@ mod tests {
#[test]
fn test_barrier() {
let barrier = Barrier::new(10);
let (port, chan) = Chan::new();
let (tx, rx) = channel();
for _ in range(0, 9) {
let c = barrier.clone();
let chan = chan.clone();
let tx = tx.clone();
spawn(proc() {
c.wait();
chan.send(true);
tx.send(true);
});
}
// At this point, all spawned tasks should be blocked,
// so we shouldn't get anything from the port
assert!(match port.try_recv() {
assert!(match rx.try_recv() {
Empty => true,
_ => false,
});
@ -1421,7 +1324,7 @@ mod tests {
barrier.wait();
// Now, the barrier is cleared and we should get data.
for _ in range(0, 9) {
port.recv();
rx.recv();
}
}
}

View File

@ -532,17 +532,17 @@ mod test {
}
}
let (p, c) = Chan::new();
let (tx, rx) = channel();
for _ in range(0, N) {
let c2 = c.clone();
native::task::spawn(proc() { inc(); c2.send(()); });
let c2 = c.clone();
spawn(proc() { inc(); c2.send(()); });
let tx2 = tx.clone();
native::task::spawn(proc() { inc(); tx2.send(()); });
let tx2 = tx.clone();
spawn(proc() { inc(); tx2.send(()); });
}
drop(c);
drop(tx);
for _ in range(0, 2 * N) {
p.recv();
rx.recv();
}
assert_eq!(unsafe {CNT}, M * N * 2);
unsafe {

View File

@ -137,9 +137,9 @@ mod test {
static mut o: Once = ONCE_INIT;
static mut run: bool = false;
let (p, c) = Chan::new();
let (tx, rx) = channel();
for _ in range(0, 10) {
let c = c.clone();
let tx = tx.clone();
spawn(proc() {
for _ in range(0, 4) { task::deschedule() }
unsafe {
@ -149,7 +149,7 @@ mod test {
});
assert!(run);
}
c.send(());
tx.send(());
});
}
@ -162,7 +162,7 @@ mod test {
}
for _ in range(0, 10) {
p.recv();
rx.recv();
}
}
}

View File

@ -23,7 +23,7 @@ enum Msg<T> {
}
pub struct TaskPool<T> {
priv channels: ~[Chan<Msg<T>>],
priv channels: ~[Sender<Msg<T>>],
priv next_index: uint,
}
@ -48,13 +48,13 @@ impl<T> TaskPool<T> {
assert!(n_tasks >= 1);
let channels = vec::from_fn(n_tasks, |i| {
let (port, chan) = Chan::<Msg<T>>::new();
let (tx, rx) = channel::<Msg<T>>();
let init_fn = init_fn_factory();
let task_body: proc() = proc() {
let local_data = init_fn(i);
loop {
match port.recv() {
match rx.recv() {
Execute(f) => f(&local_data),
Quit => break
}
@ -64,7 +64,7 @@ impl<T> TaskPool<T> {
// Run on this scheduler.
task::spawn(task_body);
chan
tx
});
return TaskPool { channels: channels, next_index: 0 };

View File

@ -53,7 +53,7 @@ use std::f64;
use std::fmt;
use std::from_str::FromStr;
use std::io::stdio::StdWriter;
use std::io::{File, PortReader, ChanWriter};
use std::io::{File, ChanReader, ChanWriter};
use std::io;
use std::os;
use std::str;
@ -827,7 +827,7 @@ fn run_tests(opts: &TestOpts,
remaining.reverse();
let mut pending = 0;
let (p, ch) = Chan::<MonitorMsg>::new();
let (tx, rx) = channel::<MonitorMsg>();
while pending > 0 || !remaining.is_empty() {
while pending < concurrency && !remaining.is_empty() {
@ -838,11 +838,11 @@ fn run_tests(opts: &TestOpts,
// that hang forever.
try!(callback(TeWait(test.desc.clone(), test.testfn.padding())));
}
run_test(!opts.run_tests, test, ch.clone());
run_test(!opts.run_tests, test, tx.clone());
pending += 1;
}
let (desc, result, stdout) = p.recv();
let (desc, result, stdout) = rx.recv();
if concurrency != 1 {
try!(callback(TeWait(desc.clone(), PadNone)));
}
@ -854,8 +854,8 @@ fn run_tests(opts: &TestOpts,
// (this includes metric fns)
for b in filtered_benchs_and_metrics.move_iter() {
try!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
run_test(!opts.run_benchmarks, b, ch.clone());
let (test, result, stdout) = p.recv();
run_test(!opts.run_benchmarks, b, tx.clone());
let (test, result, stdout) = rx.recv();
try!(callback(TeResult(test, result, stdout)));
}
Ok(())
@ -938,7 +938,7 @@ pub fn filter_tests(
pub fn run_test(force_ignore: bool,
test: TestDescAndFn,
monitor_ch: Chan<MonitorMsg>) {
monitor_ch: Sender<MonitorMsg>) {
let TestDescAndFn {desc, testfn} = test;
@ -948,13 +948,13 @@ pub fn run_test(force_ignore: bool,
}
fn run_test_inner(desc: TestDesc,
monitor_ch: Chan<MonitorMsg>,
monitor_ch: Sender<MonitorMsg>,
testfn: proc()) {
spawn(proc() {
let (p, c) = Chan::new();
let mut reader = PortReader::new(p);
let stdout = ChanWriter::new(c.clone());
let stderr = ChanWriter::new(c);
let (tx, rx) = channel();
let mut reader = ChanReader::new(rx);
let stdout = ChanWriter::new(tx.clone());
let stderr = ChanWriter::new(tx);
let mut task = task::task().named(match desc.name {
DynTestName(ref name) => name.clone().into_maybe_owned(),
StaticTestName(name) => name.into_maybe_owned(),
@ -1321,9 +1321,9 @@ mod tests {
},
testfn: DynTestFn(proc() f()),
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res, _) = p.recv();
let (tx, rx) = channel();
run_test(false, desc, tx);
let (_, res, _) = rx.recv();
assert!(res != TrOk);
}
@ -1338,9 +1338,9 @@ mod tests {
},
testfn: DynTestFn(proc() f()),
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res, _) = p.recv();
let (tx, rx) = channel();
run_test(false, desc, tx);
let (_, res, _) = rx.recv();
assert!(res == TrIgnored);
}
@ -1355,9 +1355,9 @@ mod tests {
},
testfn: DynTestFn(proc() f()),
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res, _) = p.recv();
let (tx, rx) = channel();
run_test(false, desc, tx);
let (_, res, _) = rx.recv();
assert!(res == TrOk);
}
@ -1372,9 +1372,9 @@ mod tests {
},
testfn: DynTestFn(proc() f()),
};
let (p, ch) = Chan::new();
run_test(false, desc, ch);
let (_, res, _) = p.recv();
let (tx, rx) = channel();
run_test(false, desc, tx);
let (_, res, _) = rx.recv();
assert!(res == TrFailed);
}

View File

@ -10,10 +10,10 @@
use std::task;
pub fn foo<T:Send + Clone>(x: T) -> Port<T> {
let (p, c) = Chan::new();
pub fn foo<T:Send + Clone>(x: T) -> Receiver<T> {
let (tx, rx) = channel();
task::spawn(proc() {
c.send(x.clone());
tx.send(x.clone());
});
p
rx
}

View File

@ -33,7 +33,7 @@ enum request {
stop
}
fn server(requests: &Port<request>, responses: &Chan<uint>) {
fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
let mut count = 0u;
let mut done = false;
while !done {
@ -52,8 +52,8 @@ fn server(requests: &Port<request>, responses: &Chan<uint>) {
}
fn run(args: &[~str]) {
let (from_child, to_parent) = Chan::new();
let (from_parent, to_child) = Chan::new();
let (to_parent, from_child) = channel();
let (to_child, from_parent) = channel();
let size = from_str::<uint>(args[1]).unwrap();
let workers = from_str::<uint>(args[2]).unwrap();

View File

@ -28,7 +28,7 @@ enum request {
stop
}
fn server(requests: &Port<request>, responses: &Chan<uint>) {
fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
let mut count: uint = 0;
let mut done = false;
while !done {
@ -47,7 +47,7 @@ fn server(requests: &Port<request>, responses: &Chan<uint>) {
}
fn run(args: &[~str]) {
let (from_child, to_parent) = Chan::new();
let (to_parent, from_child) = channel();
let size = from_str::<uint>(args[1]).unwrap();
let workers = from_str::<uint>(args[2]).unwrap();
@ -55,7 +55,7 @@ fn run(args: &[~str]) {
let start = time::precise_time_s();
let mut worker_results = ~[];
let from_parent = if workers == 1 {
let (from_parent, to_child) = Chan::new();
let (to_child, from_parent) = channel();
let mut builder = task::task();
worker_results.push(builder.future_result());
builder.spawn(proc() {
@ -67,7 +67,7 @@ fn run(args: &[~str]) {
});
from_parent
} else {
let (from_parent, to_child) = Chan::new();
let (to_child, from_parent) = channel();
for _ in range(0u, workers) {
let to_child = to_child.clone();
let mut builder = task::task();

View File

@ -32,25 +32,23 @@ fn ping_pong_bench(n: uint, m: uint) {
// Create pairs of tasks that pingpong back and forth.
fn run_pair(n: uint) {
// Create a stream A->B
let (pa,ca) = Chan::<()>::new();
let (atx, arx) = channel::<()>();
// Create a stream B->A
let (pb,cb) = Chan::<()>::new();
let (btx, brx) = channel::<()>();
spawn(proc() {
let chan = ca;
let port = pb;
let (tx, rx) = (atx, brx);
for _ in range(0, n) {
chan.send(());
port.recv();
tx.send(());
rx.recv();
}
});
spawn(proc() {
let chan = cb;
let port = pa;
let (tx, rx) = (btx, arx);
for _ in range(0, n) {
port.recv();
chan.send(());
rx.recv();
tx.send(());
}
});
}

View File

@ -22,12 +22,12 @@ fn parfib(n: uint) -> uint {
return 1;
}
let (port,chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
chan.send(parfib(n-1));
tx.send(parfib(n-1));
});
let m2 = parfib(n-2);
return (port.recv() + m2);
return (rx.recv() + m2);
}
fn main() {

View File

@ -99,9 +99,9 @@ fn transform(aa: color, bb: color) -> color {
fn creature(
name: uint,
color: color,
from_rendezvous: Port<Option<CreatureInfo>>,
to_rendezvous: Chan<CreatureInfo>,
to_rendezvous_log: Chan<~str>
from_rendezvous: Receiver<Option<CreatureInfo>>,
to_rendezvous: Sender<CreatureInfo>,
to_rendezvous_log: Sender<~str>
) {
let mut color = color;
let mut creatures_met = 0;
@ -137,13 +137,13 @@ fn creature(
fn rendezvous(nn: uint, set: ~[color]) {
// these ports will allow us to hear from the creatures
let (from_creatures, to_rendezvous) = Chan::<CreatureInfo>::new();
let (from_creatures_log, to_rendezvous_log) = Chan::<~str>::new();
let (to_rendezvous, from_creatures) = channel::<CreatureInfo>();
let (to_rendezvous_log, from_creatures_log) = channel::<~str>();
// these channels will be passed to the creatures so they can talk to us
// these channels will allow us to talk to each creature by 'name'/index
let to_creature: ~[Chan<Option<CreatureInfo>>] =
let to_creature: ~[Sender<Option<CreatureInfo>>] =
set.iter().enumerate().map(|(ii, col)| {
// create each creature as a listener with a port, and
// give us a channel to talk to each
@ -151,7 +151,7 @@ fn rendezvous(nn: uint, set: ~[color]) {
let col = *col;
let to_rendezvous = to_rendezvous.clone();
let to_rendezvous_log = to_rendezvous_log.clone();
let (from_rendezvous, to_creature) = Chan::new();
let (to_creature, from_rendezvous) = channel();
task::spawn(proc() {
creature(ii,
col,

View File

@ -111,8 +111,8 @@ fn windows_with_carry(bb: &[u8], nn: uint, it: |window: &[u8]|) -> ~[u8] {
}
fn make_sequence_processor(sz: uint,
from_parent: &Port<~[u8]>,
to_parent: &Chan<~str>) {
from_parent: &Receiver<~[u8]>,
to_parent: &Sender<~str>) {
let mut freqs: HashMap<~[u8], uint> = HashMap::new();
let mut carry: ~[u8] = ~[];
let mut total: uint = 0u;
@ -158,23 +158,23 @@ fn main() {
// initialize each sequence sorter
let sizes = ~[1u,2,3,4,6,12,18];
let mut streams = vec::from_fn(sizes.len(), |_| Some(Chan::<~str>::new()));
let mut streams = vec::from_fn(sizes.len(), |_| Some(channel::<~str>()));
let mut from_child = ~[];
let to_child = sizes.iter().zip(streams.mut_iter()).map(|(sz, stream_ref)| {
let to_child = sizes.iter().zip(streams.mut_iter()).map(|(sz, stream_ref)| {
let sz = *sz;
let stream = replace(stream_ref, None);
let (from_child_, to_parent_) = stream.unwrap();
let (to_parent_, from_child_) = stream.unwrap();
from_child.push(from_child_);
let (from_parent, to_child) = Chan::new();
let (to_child, from_parent) = channel();
spawn(proc() {
make_sequence_processor(sz, &from_parent, &to_parent_);
});
to_child
}).collect::<~[Chan<~[u8]>]>();
}).collect::<~[Sender<~[u8]>]>();
// latch stores true after we've started

View File

@ -27,24 +27,24 @@ use std::task;
use std::uint;
fn fib(n: int) -> int {
fn pfib(c: &Chan<int>, n: int) {
fn pfib(tx: &Sender<int>, n: int) {
if n == 0 {
c.send(0);
tx.send(0);
} else if n <= 2 {
c.send(1);
tx.send(1);
} else {
let (pp, cc) = Chan::new();
let ch = cc.clone();
task::spawn(proc() pfib(&ch, n - 1));
let ch = cc.clone();
task::spawn(proc() pfib(&ch, n - 2));
c.send(pp.recv() + pp.recv());
let (tx1, rx) = channel();
let tx2 = tx1.clone();
task::spawn(proc() pfib(&tx2, n - 1));
let tx2 = tx1.clone();
task::spawn(proc() pfib(&tx2, n - 2));
tx.send(rx.recv() + rx.recv());
}
}
let (p, ch) = Chan::new();
let _t = task::spawn(proc() pfib(&ch, n) );
p.recv()
let (tx, rx) = channel();
spawn(proc() pfib(&tx, n) );
rx.recv()
}
struct Config {

View File

@ -35,13 +35,13 @@ fn mult(v: RWArc<~[f64]>, out: RWArc<~[f64]>, f: fn(&~[f64], uint) -> f64) {
// 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 (wait_port, wait_chan) = Chan::new();
let (tx, rx) = channel();
let len = out.read(|out| out.len());
let chunk = len / 100 + 1;
for chk in count(0, chunk) {
if chk >= len {break;}
let w = wait_chan.clone();
let tx = tx.clone();
let v = v.clone();
let out = out.clone();
spawn(proc() {
@ -49,13 +49,13 @@ fn mult(v: RWArc<~[f64]>, out: RWArc<~[f64]>, f: fn(&~[f64], uint) -> f64) {
let val = v.read(|v| f(v, i));
out.write(|out| out[i] = val);
}
drop(w)
drop(tx)
});
}
// wait until the channel hang up (every task finished)
drop(wait_chan);
for () in wait_port.iter() {}
drop(tx);
for () in rx.iter() {}
}
fn mult_Av_impl(v: &~[f64], i: uint) -> f64 {

View File

@ -13,30 +13,27 @@
use std::os;
fn start(n_tasks: int, token: int) {
let (p, ch1) = Chan::new();
let mut p = p;
let ch1 = ch1;
ch1.send(token);
let (tx, mut rx) = channel();
tx.send(token);
// XXX could not get this to work with a range closure
let mut i = 2;
while i <= n_tasks {
let (next_p, ch) = Chan::new();
let (tx, next_rx) = channel();
let imm_i = i;
let imm_p = p;
let imm_rx = rx;
spawn(proc() {
roundtrip(imm_i, n_tasks, &imm_p, &ch);
roundtrip(imm_i, n_tasks, &imm_rx, &tx);
});
p = next_p;
rx = next_rx;
i += 1;
}
let imm_p = p;
let imm_ch = ch1;
let imm_rx = rx;
spawn(proc() {
roundtrip(1, n_tasks, &imm_p, &imm_ch);
roundtrip(1, n_tasks, &imm_rx, &tx);
});
}
fn roundtrip(id: int, n_tasks: int, p: &Port<int>, ch: &Chan<int>) {
fn roundtrip(id: int, n_tasks: int, p: &Receiver<int>, ch: &Sender<int>) {
loop {
match p.recv() {
1 => {

View File

@ -22,7 +22,7 @@ use std::os;
use std::task;
use std::uint;
fn child_generation(gens_left: uint, c: comm::Chan<()>) {
fn child_generation(gens_left: uint, tx: comm::Sender<()>) {
// This used to be O(n^2) in the number of generations that ever existed.
// With this code, only as many generations are alive at a time as tasks
// alive at a time,
@ -31,9 +31,9 @@ fn child_generation(gens_left: uint, c: comm::Chan<()>) {
task::deschedule(); // shake things up a bit
}
if gens_left > 0 {
child_generation(gens_left - 1, c); // recurse
child_generation(gens_left - 1, tx); // recurse
} else {
c.send(())
tx.send(())
}
});
}
@ -48,9 +48,9 @@ fn main() {
args.clone()
};
let (p,c) = Chan::new();
child_generation(from_str::<uint>(args[1]).unwrap(), c);
if p.recv_opt().is_none() {
let (tx, rx) = channel();
child_generation(from_str::<uint>(args[1]).unwrap(), tx);
if rx.recv_opt().is_none() {
fail!("it happened when we slumbered");
}
}

View File

@ -17,24 +17,24 @@ use std::task;
use std::uint;
use std::vec;
fn calc(children: uint, parent_wait_chan: &Chan<Chan<Chan<int>>>) {
fn calc(children: uint, parent_wait_chan: &Sender<Sender<Sender<int>>>) {
let wait_ports: ~[Port<Chan<Chan<int>>>] = vec::from_fn(children, |_| {
let (wait_port, wait_chan) = stream::<Chan<Chan<int>>>();
let wait_ports: ~[Receiver<Sender<Sender<int>>>] = vec::from_fn(children, |_| {
let (wait_port, wait_chan) = stream::<Sender<Sender<int>>>();
task::spawn(proc() {
calc(children / 2, &wait_chan);
});
wait_port
});
let child_start_chans: ~[Chan<Chan<int>>] =
let child_start_chans: ~[Sender<Sender<int>>] =
wait_ports.move_iter().map(|port| port.recv()).collect();
let (start_port, start_chan) = stream::<Chan<int>>();
let (start_port, start_chan) = stream::<Sender<int>>();
parent_wait_chan.send(start_chan);
let parent_result_chan: Chan<int> = start_port.recv();
let parent_result_chan: Sender<int> = start_port.recv();
let child_sum_ports: ~[Port<int>] =
let child_sum_ports: ~[Receiver<int>] =
child_start_chans.move_iter().map(|child_start_chan| {
let (child_sum_port, child_sum_chan) = stream::<int>();
child_start_chan.send(child_sum_chan);

View File

@ -9,9 +9,9 @@
// except according to those terms.
fn main() {
let (p,c) = Chan::new();
let x = Some(p);
c.send(false);
let (tx, rx) = channel();
let x = Some(rx);
tx.send(false);
match x {
Some(z) if z.recv() => { fail!() }, //~ ERROR cannot bind by-move into a pattern guard
Some(z) => { assert!(!z.recv()); },

View File

@ -65,4 +65,4 @@ fn assign3<'a>(x: &'a mut Own<int>) {
**x = 3;
}
pub fn main() {}
pub fn main() {}

View File

@ -12,7 +12,7 @@
// to use capabilities granted by builtin kinds as supertraits.
trait Foo : Freeze {
fn foo(self, mut chan: Chan<Self>) {
fn foo(self, mut chan: Sender<Self>) {
chan.send(self); //~ ERROR does not fulfill `Send`
}
}
@ -20,7 +20,7 @@ trait Foo : Freeze {
impl <T: Freeze> Foo for T { }
fn main() {
let (p,c) = Chan::new();
1193182.foo(c);
assert!(p.recv() == 1193182);
let (tx, rx) = channel();
1193182.foo(tx);
assert!(rx.recv() == 1193182);
}

View File

@ -11,7 +11,7 @@
fn test<T: Freeze>() {}
fn main() {
test::<Chan<int>>(); //~ ERROR: does not fulfill `Freeze`
test::<Port<int>>(); //~ ERROR: does not fulfill `Freeze`
test::<Chan<int>>(); //~ ERROR: does not fulfill `Freeze`
test::<Sender<int>>(); //~ ERROR: does not fulfill `Freeze`
test::<Receiver<int>>(); //~ ERROR: does not fulfill `Freeze`
test::<Sender<int>>(); //~ ERROR: does not fulfill `Freeze`
}

View File

@ -21,4 +21,4 @@ extern {
fn this_is_actually_ok(a: uint);
fn and_so_is_this(_: uint);
}
fn main() {}
fn main() {}

View File

@ -27,6 +27,6 @@ fn foo(i:int, j: @~str) -> foo {
fn main() {
let cat = ~"kitty";
let (_, ch) = Chan::new(); //~ ERROR does not fulfill `Send`
ch.send(foo(42, @(cat))); //~ ERROR does not fulfill `Send`
let (tx, _) = channel(); //~ ERROR does not fulfill `Send`
tx.send(foo(42, @(cat))); //~ ERROR does not fulfill `Send`
}

View File

@ -67,4 +67,4 @@ fn main() {
}
#[inline(never)]
fn zzz() { () }
fn zzz() { () }

View File

@ -20,12 +20,12 @@ trait Foo : Bar { }
impl <T: Send> Foo for T { }
impl <T: Send> Bar for T { }
fn foo<T: Foo>(val: T, chan: Chan<T>) {
fn foo<T: Foo>(val: T, chan: Sender<T>) {
chan.send(val);
}
pub fn main() {
let (p,c) = Chan::new();
foo(31337, c);
assert!(p.recv() == 31337);
let (tx, rx) = channel();
foo(31337, tx);
assert!(rx.recv() == 31337);
}

View File

@ -24,12 +24,12 @@ struct X<T>(T);
impl <T: Freeze> RequiresFreeze for X<T> { }
impl <T: Freeze+Send> RequiresRequiresFreezeAndSend for X<T> { }
fn foo<T: RequiresRequiresFreezeAndSend>(val: T, chan: Chan<T>) {
fn foo<T: RequiresRequiresFreezeAndSend>(val: T, chan: Sender<T>) {
chan.send(val);
}
pub fn main() {
let (p,c) = Chan::new();
foo(X(31337), c);
assert!(p.recv() == X(31337));
let (tx, rx) = channel();
foo(X(31337), tx);
assert!(rx.recv() == X(31337));
}

View File

@ -16,12 +16,12 @@ trait Foo : Send { }
impl <T: Send> Foo for T { }
fn foo<T: Foo>(val: T, chan: Chan<T>) {
fn foo<T: Foo>(val: T, chan: Sender<T>) {
chan.send(val);
}
pub fn main() {
let (p,c) = Chan::new();
foo(31337, c);
assert!(p.recv() == 31337);
let (tx, rx) = channel();
foo(31337, tx);
assert!(rx.recv() == 31337);
}

View File

@ -12,15 +12,15 @@
// capabilities granted by builtin kinds as supertraits.
trait Foo : Send {
fn foo(self, chan: Chan<Self>) {
chan.send(self);
fn foo(self, tx: Sender<Self>) {
tx.send(self);
}
}
impl <T: Send> Foo for T { }
pub fn main() {
let (p,c) = Chan::new();
1193182.foo(c);
assert!(p.recv() == 1193182);
let (tx, rx) = channel();
1193182.foo(tx);
assert!(rx.recv() == 1193182);
}

View File

@ -26,12 +26,12 @@
use std::task;
fn foo(x: ()) -> Port<()> {
let (p, c) = Chan::<()>::new();
fn foo(x: ()) -> Receiver<()> {
let (tx, rx) = channel::<()>();
task::spawn(proc() {
c.send(x);
tx.send(x);
});
p
rx
}
pub fn main() {

View File

@ -16,7 +16,7 @@
extern crate native;
use std::fmt;
use std::io::{PortReader, ChanWriter};
use std::io::{ChanReader, ChanWriter};
use std::logging::{set_logger, Logger};
struct MyWriter(ChanWriter);
@ -36,8 +36,8 @@ fn start(argc: int, argv: **u8) -> int {
}
fn main() {
let (p, c) = Chan::new();
let (mut r, w) = (PortReader::new(p), ChanWriter::new(c));
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
spawn(proc() {
set_logger(~MyWriter(w) as ~Logger);
debug!("debug");

View File

@ -15,9 +15,9 @@ fn foo(blk: proc()) {
}
pub fn main() {
let (p,c) = Chan::new();
let (tx, rx) = channel();
foo(proc() {
c.send(());
tx.send(());
});
p.recv();
rx.recv();
}

View File

@ -11,15 +11,15 @@
use std::task;
pub fn main() {
let (p, ch) = Chan::new();
let _t = task::spawn(proc() { child(&ch) });
let y = p.recv();
let (tx, rx) = channel();
let _t = task::spawn(proc() { child(&tx) });
let y = rx.recv();
error!("received");
error!("{:?}", y);
assert_eq!(y, 10);
}
fn child(c: &Chan<int>) {
fn child(c: &Sender<int>) {
error!("sending");
c.send(10);
error!("value sent");

View File

@ -31,9 +31,9 @@ mod map_reduce {
pub type mapper = extern fn(~str, putter);
enum ctrl_proto { find_reducer(~[u8], Chan<int>), mapper_done, }
enum ctrl_proto { find_reducer(~[u8], Sender<int>), mapper_done, }
fn start_mappers(ctrl: Chan<ctrl_proto>, inputs: ~[~str]) {
fn start_mappers(ctrl: Sender<ctrl_proto>, inputs: ~[~str]) {
for i in inputs.iter() {
let ctrl = ctrl.clone();
let i = i.clone();
@ -41,20 +41,20 @@ mod map_reduce {
}
}
fn map_task(ctrl: Chan<ctrl_proto>, input: ~str) {
fn map_task(ctrl: Sender<ctrl_proto>, input: ~str) {
let mut intermediates = HashMap::new();
fn emit(im: &mut HashMap<~str, int>,
ctrl: Chan<ctrl_proto>, key: ~str,
ctrl: Sender<ctrl_proto>, key: ~str,
_val: ~str) {
if im.contains_key(&key) {
return;
}
let (pp, cc) = Chan::new();
let (tx, rx) = channel();
error!("sending find_reducer");
ctrl.send(find_reducer(key.as_bytes().to_owned(), cc));
ctrl.send(find_reducer(key.as_bytes().to_owned(), tx));
error!("receiving");
let c = pp.recv();
let c = rx.recv();
error!("{:?}", c);
im.insert(key, c);
}
@ -65,7 +65,7 @@ mod map_reduce {
}
pub fn map_reduce(inputs: ~[~str]) {
let (ctrl_port, ctrl_chan) = Chan::new();
let (tx, rx) = channel();
// This task becomes the master control task. It spawns others
// to do the rest.
@ -74,12 +74,12 @@ mod map_reduce {
reducers = HashMap::new();
start_mappers(ctrl_chan, inputs.clone());
start_mappers(tx, inputs.clone());
let mut num_mappers = inputs.len() as int;
while num_mappers > 0 {
match ctrl_port.recv() {
match rx.recv() {
mapper_done => { num_mappers -= 1; }
find_reducer(k, cc) => {
let mut c;

View File

@ -10,7 +10,6 @@
extern crate extra;
use std::comm::Chan;
use std::task;
type RingBuffer = ~[f64];
@ -21,7 +20,7 @@ enum Msg
GetSamples(~str, SamplesFn), // sample set name, callback which receives samples
}
fn foo(name: ~str, samples_chan: Chan<Msg>) {
fn foo(name: ~str, samples_chan: Sender<Msg>) {
task::spawn(proc() {
let mut samples_chan = samples_chan;
let callback: SamplesFn = proc(buffer) {

View File

@ -11,11 +11,11 @@
use std::io::println;
pub fn main() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
println(port.recv());
println(rx.recv());
});
chan.send("hello, world");
tx.send("hello, world");
}

View File

@ -11,11 +11,11 @@
use std::task;
pub fn main() {
let (port, chan) = Chan::<&'static str>::new();
let (tx, rx) = channel::<&'static str>();
task::spawn(proc() {
assert_eq!(port.recv(), "hello, world");
assert_eq!(rx.recv(), "hello, world");
});
chan.send("hello, world");
tx.send("hello, world");
}

View File

@ -12,14 +12,14 @@ use std::comm;
use std::io::timer::Timer;
pub fn main() {
let (port, chan) = Chan::new();
let (tx, rx) = channel();
spawn(proc (){
let mut timer = Timer::new().unwrap();
timer.sleep(10);
chan.send(());
tx.send(());
});
loop {
match port.try_recv() {
match rx.try_recv() {
comm::Data(()) => break,
comm::Empty => {}
comm::Disconnected => unreachable!()

View File

@ -10,17 +10,17 @@
use std::task;
fn producer(c: &Chan<~[u8]>) {
c.send(
fn producer(tx: &Sender<~[u8]>) {
tx.send(
~[1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8,
13u8]);
}
pub fn main() {
let (p, ch) = Chan::<~[u8]>::new();
let (tx, rx) = channel::<~[u8]>();
let _prod = task::spawn(proc() {
producer(&ch)
producer(&tx)
});
let _data: ~[u8] = p.recv();
let _data: ~[u8] = rx.recv();
}

View File

@ -26,13 +26,13 @@ impl fmt::Show for Foo {
}
pub fn main() {
let (p,c) = Chan::new();
let (tx, rx) = channel();
spawn(proc() {
let mut f = Foo(Cell::new(0));
debug!("{}", f);
let Foo(ref mut f) = f;
assert!(f.get() == 1);
c.send(());
tx.send(());
});
p.recv();
rx.recv();
}

View File

@ -17,7 +17,7 @@ extern crate extra;
use std::comm;
use extra::comm;
fn starve_main(alive: Port<int>) {
fn starve_main(alive: Receiver<int>) {
info!("signalling main");
alive.recv();
info!("starving main");

View File

@ -25,14 +25,14 @@ fn test(f: int) -> test {
}
pub fn main() {
let (p, c) = Chan::new();
let (tx, rx) = channel();
task::spawn(proc() {
let (pp, cc) = Chan::new();
c.send(cc);
let (tx2, rx2) = channel();
tx.send(tx2);
let _r = pp.recv();
let _r = rx2.recv();
});
p.recv().send(test(42));
rx.recv().send(test(42));
}

View File

@ -14,8 +14,8 @@ struct Command<K, V> {
val: V
}
fn cache_server<K:Send,V:Send>(mut c: Chan<Chan<Command<K, V>>>) {
let (_ctrl_port, ctrl_chan) = Chan::new();
c.send(ctrl_chan);
fn cache_server<K:Send,V:Send>(mut tx: Sender<Sender<Command<K, V>>>) {
let (tx1, _rx) = channel();
tx.send(tx1);
}
pub fn main() { }

View File

@ -23,6 +23,6 @@ fn foo(i:int, j: char) -> foo {
}
pub fn main() {
let (_po, ch) = Chan::new();
ch.send(foo(42, 'c'));
let (tx, rx) = channel();
tx.send(foo(42, 'c'));
}

View File

@ -16,13 +16,13 @@
use std::task;
type ctx = Chan<int>;
type ctx = Sender<int>;
fn iotask(_cx: &ctx, ip: ~str) {
fn iotask(_tx: &ctx, ip: ~str) {
assert_eq!(ip, ~"localhost");
}
pub fn main() {
let (_p, ch) = Chan::<int>::new();
task::spawn(proc() iotask(&ch, ~"localhost") );
let (tx, _rx) = channel::<int>();
task::spawn(proc() iotask(&tx, ~"localhost") );
}

View File

@ -16,23 +16,23 @@ use std::task;
pub fn main() { test05(); }
fn test05_start(ch : &Chan<int>) {
ch.send(10);
fn test05_start(tx : &Sender<int>) {
tx.send(10);
error!("sent 10");
ch.send(20);
tx.send(20);
error!("sent 20");
ch.send(30);
tx.send(30);
error!("sent 30");
}
fn test05() {
let (po, ch) = Chan::new();
task::spawn(proc() { test05_start(&ch) });
let mut value: int = po.recv();
let (tx, rx) = channel();
task::spawn(proc() { test05_start(&tx) });
let mut value: int = rx.recv();
error!("{}", value);
value = po.recv();
value = rx.recv();
error!("{}", value);
value = po.recv();
value = rx.recv();
error!("{}", value);
assert_eq!(value, 30);
}

View File

@ -14,25 +14,25 @@ extern crate extra;
use std::task;
fn start(c: &Chan<Chan<~str>>) {
let (p, ch) = Chan::new();
c.send(ch);
fn start(tx: &Sender<Sender<~str>>) {
let (tx2, rx) = channel();
tx.send(tx2);
let mut a;
let mut b;
a = p.recv();
a = rx.recv();
assert!(a == ~"A");
error!("{:?}", a);
b = p.recv();
b = rx.recv();
assert!(b == ~"B");
error!("{:?}", b);
}
pub fn main() {
let (p, ch) = Chan::new();
let _child = task::spawn(proc() { start(&ch) });
let (tx, rx) = channel();
let _child = task::spawn(proc() { start(&tx) });
let mut c = p.recv();
let mut c = rx.recv();
c.send(~"A");
c.send(~"B");
task::deschedule();

View File

@ -14,15 +14,15 @@ extern crate extra;
use std::task;
fn start(c: &Chan<Chan<int>>) {
let (_p, ch) = Chan::new();
c.send(ch);
fn start(tx: &Sender<Sender<int>>) {
let (tx2, _rx) = channel();
tx.send(tx2);
}
pub fn main() {
let (mut p, ch) = Chan::new();
let (tx, rx) = channel();
let _child = task::spawn(proc() {
start(&ch)
start(&tx)
});
let _c = p.recv();
let _tx = rx.recv();
}

View File

@ -14,14 +14,14 @@ extern crate extra;
use std::task;
fn start(c: &Chan<int>, start: int, number_of_messages: int) {
fn start(tx: &Sender<int>, start: int, number_of_messages: int) {
let mut i: int = 0;
while i < number_of_messages { c.send(start + i); i += 1; }
while i < number_of_messages { tx.send(start + i); i += 1; }
}
pub fn main() {
info!("Check that we don't deadlock.");
let (_p, ch) = Chan::new();
task::try(proc() { start(&ch, 0, 10) });
let (tx, rx) = channel();
task::try(proc() { start(&tx, 0, 10) });
info!("Joined task");
}

Some files were not shown because too many files have changed in this diff Show More