about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-01-11 09:48:57 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-01-11 09:49:21 -0800
commitf3b867fd04d06c732a41e05c3abddb8e8bcbdbbb (patch)
tree29b0b24f07769e6ccefda5ab2d7a901e1c8b30ff
parente0cf550527fe1cd6934dd4e25ea03ecb17f76c6f (diff)
downloadrust-f3b867fd04d06c732a41e05c3abddb8e8bcbdbbb.tar.gz
rust-f3b867fd04d06c732a41e05c3abddb8e8bcbdbbb.zip
add section on spawn_connected to tutorial and pull test into file
-rw-r--r--doc/tutorial/task.md49
-rw-r--r--src/test/run-pass/task-spawn-connected.rs18
-rw-r--r--src/test/stdtest/task.rs19
3 files changed, 67 insertions, 19 deletions
diff --git a/doc/tutorial/task.md b/doc/tutorial/task.md
index b373e27dc21..1b8ba6769ca 100644
--- a/doc/tutorial/task.md
+++ b/doc/tutorial/task.md
@@ -74,3 +74,52 @@ to arrive on the port:
     some_other_expensive_computation();
     let result = comm::recv(port);
 
+## Creating a task with a bi-directional communication path
+
+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 `task::spawn_connected()` supports this pattern.  We'll look
+briefly at how it is used.
+
+To see how `spawn_connected()` works, we will create a child task
+which receives `uint` messages, converts them to a string, and sends
+the string in response.  The child terminates when `0` is received.
+Here is the function which implements the child task:
+
+    fn stringifier(from_par: comm::port<uint>,
+                   to_par: comm::chan<str>) {
+        let value: uint;
+        do {
+            value = comm::recv(from_par);
+            comm::send(to_par, uint::to_str(value, 10u));
+        } while value != 0u;
+    }
+    
+You can see that the function takes two parameters.  The first is a
+port used to receive messages from the parent, and the second is a
+channel used to send messages to the parent.  The body itself simply
+loops, reading from the `from_par` port and then sending its response
+to the `to_par` channel.  The actual response itself is simply the
+strified version of the received value, `uint::to_str(value)`.
+
+Here is the code for the parent task:
+    
+    fn main() {
+        let t = task::spawn_connected(stringifier);
+        comm::send(t.to_child, 22u);
+        assert comm::recv(t.from_child) == "22";
+        comm::send(t.to_child, 23u);
+        assert comm::recv(t.from_child) == "23";
+        comm::send(t.to_child, 0u);
+        assert comm::recv(t.from_child) == "0";
+    }
+
+The call to `spawn_connected()` on the first line will instantiate the
+various ports and channels and startup the child task.  The returned
+value, `t`, is a record of type `task::connected_task<uint,str>`.  In
+addition to the task id of the child, this record defines two fields,
+`from_child` and `to_child`, which contain the port and channel
+respectively for communicating with the child.  Those fields are used
+here to send and receive three messages from the child task.
+
+
diff --git a/src/test/run-pass/task-spawn-connected.rs b/src/test/run-pass/task-spawn-connected.rs
new file mode 100644
index 00000000000..053dab56a05
--- /dev/null
+++ b/src/test/run-pass/task-spawn-connected.rs
@@ -0,0 +1,18 @@
+fn stringifier(from_par: comm::port<uint>,
+               to_par: comm::chan<str>) {
+    let value: uint;
+    do {
+        value = comm::recv(from_par);
+        comm::send(to_par, uint::to_str(value, 10u));
+    } while value != 0u;
+}
+
+fn main() {
+    let t = task::spawn_connected(stringifier);
+    comm::send(t.to_child, 22u);
+    assert comm::recv(t.from_child) == "22";
+    comm::send(t.to_child, 23u);
+    assert comm::recv(t.from_child) == "23";
+    comm::send(t.to_child, 0u);
+    assert comm::recv(t.from_child) == "0";
+}
\ No newline at end of file
diff --git a/src/test/stdtest/task.rs b/src/test/stdtest/task.rs
index 021dee4bc98..d1408d183d5 100644
--- a/src/test/stdtest/task.rs
+++ b/src/test/stdtest/task.rs
@@ -57,22 +57,3 @@ fn spawn_polymorphic() {
     task::spawn {|| foo(true);};
     task::spawn {|| foo(42);};
 }
-
-#[test]
-fn spawn_connected_stringifier() {
-    fn stringifer(p: comm::port<uint>, ch: comm::chan<str>) {
-        let u = 1u;
-        while u != 0u {
-            u = comm::recv(p);
-            comm::send(ch, uint::to_str(u, 10u));
-        }
-    }
-
-    let ch = task::spawn_connected(stringifer);
-    comm::send(ch.to_child, 22u);
-    assert "22" == comm::recv(ch.from_child);
-    comm::send(ch.to_child, 44u);
-    assert "44" == comm::recv(ch.from_child);
-    comm::send(ch.to_child, 0u);
-    assert "0" == comm::recv(ch.from_child);
-}
\ No newline at end of file