diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-01-24 10:02:27 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-01-24 10:05:58 -0800 |
| commit | 35e26e94d8a13ef3f24a66374aff815e370f8843 (patch) | |
| tree | a9b1083e808c9b25238b213141de708c9d481285 /src/libstd/comm/select.rs | |
| parent | 657e3530225410d167d7f1ee827f15bc69cd965e (diff) | |
| download | rust-35e26e94d8a13ef3f24a66374aff815e370f8843.tar.gz rust-35e26e94d8a13ef3f24a66374aff815e370f8843.zip | |
Fix a spuriously tripped assert in select()
The race here happened when a port had its deschedule in select() canceled, but the other chan had already been dropped. This meant that the DISCONNECTED case was hit in abort_selection, but the to_wake cell hadn't been emptied yet (this was done after aborting), causing an assert in abort_selection to trip. To fix this, the to_wake cell is just emptied before abort_selection is called (we know that we're the owner of it already).
Diffstat (limited to 'src/libstd/comm/select.rs')
| -rw-r--r-- | src/libstd/comm/select.rs | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/src/libstd/comm/select.rs b/src/libstd/comm/select.rs index 6a10ac56a4e..5aa8687a5bb 100644 --- a/src/libstd/comm/select.rs +++ b/src/libstd/comm/select.rs @@ -199,11 +199,14 @@ impl Select { if (*packet).decrement() { Ok(()) } else { + // Empty to_wake first to avoid tripping an assertion in + // abort_selection in the disconnected case. + let task = (*packet).to_wake.take_unwrap(); (*packet).abort_selection(false); (*packet).selecting.store(false, SeqCst); ready_index = i; ready_id = (*packet).selection_id; - Err((*packet).to_wake.take_unwrap()) + Err(task) } }); |
