1
Fork 0

core: Don't fail during port dtor

This commit is contained in:
Brian Anderson 2012-05-15 11:51:24 -07:00
parent 7277cd7198
commit c424b7f847

View file

@ -93,25 +93,27 @@ fn listen<T: send, U>(f: fn(chan<T>) -> U) -> U {
f(po.chan()) f(po.chan())
} }
resource port_ptr<T: send>(po: *rust_port) { resource port_ptr<T: send>(po: *rust_port) unsafe {
// Once the port is detached it's guaranteed not to receive further task::unkillable {||
// messages // Once the port is detached it's guaranteed not to receive further
let yield = 0u; // messages
let yieldp = ptr::addr_of(yield); let yield = 0u;
rustrt::rust_port_begin_detach(po, yieldp); let yieldp = ptr::addr_of(yield);
if yield != 0u { rustrt::rust_port_begin_detach(po, yieldp);
// Need to wait for the port to be detached if yield != 0u {
// FIXME: If this fails then we're going to leave our port // Need to wait for the port to be detached
// in a bogus state. (Issue #1988) // FIXME: If this fails then we're going to leave our port
task::yield(); // in a bogus state. (Issue #1988)
} task::yield();
rustrt::rust_port_end_detach(po); }
rustrt::rust_port_end_detach(po);
// Drain the port so that all the still-enqueued items get dropped // Drain the port so that all the still-enqueued items get dropped
while rustrt::rust_port_size(po) > 0u { while rustrt::rust_port_size(po) > 0u {
recv_::<T>(po); recv_::<T>(po);
}
rustrt::del_port(po);
} }
rustrt::del_port(po);
} }
#[doc = " #[doc = "
@ -458,4 +460,25 @@ fn test_listen() {
} }
assert parent.recv() == "oatmeal-salad"; assert parent.recv() == "oatmeal-salad";
} }
}
#[test]
#[ignore(cfg(target_os="win32"))]
fn test_port_detach_fail() {
iter::repeat(100u) {||
let builder = task::builder();
task::unsupervise(builder);
task::run(builder) {||
let po = port();
let ch = po.chan();
task::spawn {||
fail;
}
task::spawn {||
ch.send(());
}
}
}
} }