Closed

Description
This is reproduce able 100% with the following code. Looking at the disassembly the problem is that one of the handles drop function is called after the select drop is called.
use std::comm::{Port, Chan, Select};
fn wait_commands(cmd: &mut Port<Port<()>>, ports: &mut ~[Port<()>]) -> Port<()>
{
let mut handles = ~[];
let select = Select::new();
let mut cmd_handle = select.add(cmd);
for port in ports.mut_iter() {
handles.push(select.add(port));
}
loop {
let id = select.wait();
if id == cmd_handle.id {
let port = cmd_handle.recv();
println!("{:?}", port);
return port;
}
for h in handles.mut_iter() {
if h.id == id {
break;
}
}
}
}
fn thread(cmd: Port<Port<()>>)
{
let mut cmd = cmd;
let mut ports: ~[Port<()>] = ~[];
loop {
let port = wait_commands(&mut cmd, &mut ports);
println!("{:?}", port);
ports.push(port);
}
}
fn main()
{
let (p, c) = Chan::new();
spawn(proc() {
thread(p);
});
let (new_p0, new_c0): (Port<()>, Chan<()>) = Chan::new();
let (new_p1, new_c1): (Port<()>, Chan<()>) = Chan::new();
c.send(new_p0);
c.send(new_p1);
new_c0.send(());
new_c1.send(());
}
output
std::comm::Port<()>{queue: SPSC(std::sync::spsc_queue::Consumer<(),std::comm::Packet>{state: std::sync::arc::UnsafeArc<std::sync::spsc_queue::State<(),std::comm::Packet>>{data: (0x7f435c001640 as *mut ())}}), marker: std::kinds::marker::NoFreeze}
std::comm::Port<()>{queue: SPSC(std::sync::spsc_queue::Consumer<(),std::comm::Packet>{state: std::sync::arc::UnsafeArc<std::sync::spsc_queue::State<(),std::comm::Packet>>{data: (0x7f435c001640 as *mut ())}}), marker: std::kinds::marker::NoFreeze}
std::comm::Port<()>{queue: SPSC(std::sync::spsc_queue::Consumer<(),std::comm::Packet>{state: std::sync::arc::UnsafeArc<std::sync::spsc_queue::State<(),std::comm::Packet>>{data: (0x7f435c001740 as *mut ())}}), marker: std::kinds::marker::NoFreeze}
task '<unnamed>' failed at 'assertion failed: self.head.is_null()', /build/buildd/rust-nightly-201402020405~3e39e3e~precise/src/libstd/comm/select.rs:298