1
Fork 0

Remember to wake up blocked task on sender terminate.

This commit is contained in:
Eric Holk 2012-07-09 16:57:47 -07:00
parent 1c1b3a3339
commit d07e537fc3
2 changed files with 40 additions and 1 deletions

View file

@ -156,7 +156,16 @@ fn peek<T: send>(p: recv_packet<T>) -> bool {
fn sender_terminate<T: send>(p: *packet<T>) { fn sender_terminate<T: send>(p: *packet<T>) {
let p = unsafe { uniquify(p) }; let p = unsafe { uniquify(p) };
alt swap_state_rel(p.header.state, terminated) { 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. // The receiver will eventually clean up.
unsafe { forget(p) } unsafe { forget(p) }
} }

View file

@ -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);
}