Skip to content

Commit d07e537

Browse files
committed
Remember to wake up blocked task on sender terminate.
1 parent 1c1b3a3 commit d07e537

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/libcore/pipes.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,16 @@ fn peek<T: send>(p: recv_packet<T>) -> bool {
156156
fn sender_terminate<T: send>(p: *packet<T>) {
157157
let p = unsafe { uniquify(p) };
158158
alt swap_state_rel(p.header.state, terminated) {
159-
empty | blocked {
159+
empty {
160+
// The receiver will eventually clean up.
161+
unsafe { forget(p) }
162+
}
163+
blocked {
164+
// wake up the target
165+
let target = p.header.blocked_task.get();
166+
rustrt::task_signal_event(target,
167+
ptr::addr_of(p.header) as *libc::c_void);
168+
160169
// The receiver will eventually clean up.
161170
unsafe { forget(p) }
162171
}

src/test/run-pass/pipe-detect-term.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Make sure that we can detect when one end of the pipe is closed.
2+
3+
// xfail-pretty
4+
5+
use std;
6+
import std::timer::sleep;
7+
import std::uv;
8+
9+
import pipes::{recv};
10+
11+
proto! oneshot {
12+
waiting:send {
13+
signal -> signaled
14+
}
15+
16+
signaled:send { }
17+
}
18+
19+
fn main() {
20+
let iotask = uv::global_loop::get();
21+
22+
let c = pipes::spawn_service(oneshot::init, |p| {
23+
alt recv(p) {
24+
some(*) { fail }
25+
none { }
26+
}
27+
});
28+
29+
sleep(iotask, 1000);
30+
}

0 commit comments

Comments
 (0)