about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Holk <eric.holk@gmail.com>2012-07-09 16:57:47 -0700
committerEric Holk <eric.holk@gmail.com>2012-07-10 22:00:46 -0700
commitd07e537fc3daaf73b7baf652e13ee2d36706258e (patch)
tree9a6c2ad760980508f72d8971f2fab7c1866e0dfb /src
parent1c1b3a33397a38bf412e242b8f00abfa49ed78bd (diff)
downloadrust-d07e537fc3daaf73b7baf652e13ee2d36706258e.tar.gz
rust-d07e537fc3daaf73b7baf652e13ee2d36706258e.zip
Remember to wake up blocked task on sender terminate.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/pipes.rs11
-rw-r--r--src/test/run-pass/pipe-detect-term.rs30
2 files changed, 40 insertions, 1 deletions
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index 6f61b12ab40..441f323d7bf 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -156,7 +156,16 @@ fn peek<T: send>(p: recv_packet<T>) -> bool {
 fn sender_terminate<T: send>(p: *packet<T>) {
     let p = unsafe { uniquify(p) };
     alt swap_state_rel(p.header.state, terminated) {
-      empty | blocked {
+      empty {
+        // The receiver will eventually clean up.
+        unsafe { forget(p) }
+      }
+      blocked {
+        // wake up the target
+        let target = p.header.blocked_task.get();
+        rustrt::task_signal_event(target,
+                                  ptr::addr_of(p.header) as *libc::c_void);
+
         // The receiver will eventually clean up.
         unsafe { forget(p) }
       }
diff --git a/src/test/run-pass/pipe-detect-term.rs b/src/test/run-pass/pipe-detect-term.rs
new file mode 100644
index 00000000000..6a80fd46f34
--- /dev/null
+++ b/src/test/run-pass/pipe-detect-term.rs
@@ -0,0 +1,30 @@
+// Make sure that we can detect when one end of the pipe is closed.
+
+// xfail-pretty
+
+use std;
+import std::timer::sleep;
+import std::uv;
+
+import pipes::{recv};
+
+proto! oneshot {
+    waiting:send {
+        signal -> signaled
+    }
+
+    signaled:send { }
+}
+
+fn main() {
+    let iotask = uv::global_loop::get();
+    
+    let c = pipes::spawn_service(oneshot::init, |p| { 
+        alt recv(p) {
+          some(*) { fail }
+          none { }
+        }
+    });
+
+    sleep(iotask, 1000);
+}