diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 052efdf3b41e5..0c81c7c824446 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -396,6 +396,23 @@ fn try_recv(-p: recv_packet_buffered) let p_ = p.unwrap(); let p = unsafe { &*p_ }; + struct drop_state { + p: &packet_header; + + drop { + if task::failing() { + io::println("failing!"); + self.p.state = terminated; + let old_task = swap_task(self.p.blocked_task, ptr::null()); + if !old_task.is_null() { + rustrt::rust_task_deref(old_task); + } + } + } + }; + + let _drop_state = drop_state { p: &p.header }; + // optimistic path match p.header.state { full => { diff --git a/src/test/run-pass/issue-3168.rs b/src/test/run-pass/issue-3168.rs new file mode 100644 index 0000000000000..421813962e491 --- /dev/null +++ b/src/test/run-pass/issue-3168.rs @@ -0,0 +1,19 @@ +fn main() { + let (c,p) = pipes::stream(); + do task::try { + let (c2,p2) = pipes::stream(); + do task::spawn { + p2.recv(); + #error["brother fails"]; + fail; + } + let (c3,p3) = pipes::stream(); + c.send(c3); + c2.send(()); + #error["child blocks"]; + p3.recv(); + }; + #error["parent tries"]; + assert !p.recv().try_send(()); + #error("all done!"); +}