diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2013-08-01 21:57:58 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2013-08-02 17:31:44 -0400 |
| commit | cde6ad39920ddadd7c70921232ae92adff258367 (patch) | |
| tree | 242bfb44453dd28dbcc0614cb3efbb394025b413 /src/libstd | |
| parent | be7738bfa18989438e3597847cd6a7f3bbbfac12 (diff) | |
| download | rust-cde6ad39920ddadd7c70921232ae92adff258367.tar.gz rust-cde6ad39920ddadd7c70921232ae92adff258367.zip | |
Fix nasty double-free bug where a newrt chan could get killed after rescheduling but before suppressing_finalize.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rt/comm.rs | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index c19ac8aa337..a060059f5fc 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -131,6 +131,13 @@ impl<T> ChanOne<T> { // acquire barrier that keeps the subsequent access of the // ~Task pointer from being reordered. let oldstate = (*packet).state.swap(STATE_ONE, SeqCst); + + // Suppress the synchronizing actions in the finalizer. We're + // done with the packet. NB: In case of do_resched, this *must* + // happen before waking up a blocked task (or be unkillable), + // because we might get a kill signal during the reschedule. + this.suppress_finalize = true; + match oldstate { STATE_BOTH => { // Port is not waiting yet. Nothing to do @@ -165,8 +172,6 @@ impl<T> ChanOne<T> { } } - // Suppress the synchronizing actions in the finalizer. We're done with the packet. - this.suppress_finalize = true; return recvr_active; } } |
