From cde6ad39920ddadd7c70921232ae92adff258367 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 1 Aug 2013 21:57:58 -0400 Subject: [PATCH] Fix nasty double-free bug where a newrt chan could get killed after rescheduling but before suppressing_finalize. --- src/libstd/rt/comm.rs | 9 +++++++-- 1 file 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 ChanOne { // 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 ChanOne { } } - // Suppress the synchronizing actions in the finalizer. We're done with the packet. - this.suppress_finalize = true; return recvr_active; } }