From b38d483b742eafc7833fac1ebb4fa1481cbac179 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Thu, 10 Apr 2014 10:56:55 -0700 Subject: Fix race condition in TransitionCollector. There was a race condition where if multiple threads were calling TransitionCollector it could cause a crash due to an invalid collector transition if another thread did the collector transition before the SuspendAll. Bug: 13929101 Change-Id: I8c162a83c1f53d0cbdefab62b0a5bcbb151d6c42 --- runtime/gc/heap.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'runtime/gc') diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 91f249a..fcf9fe9 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -1408,6 +1408,13 @@ void Heap::TransitionCollector(CollectorType collector_type) { MutexLock mu(self, *gc_complete_lock_); // Ensure there is only one GC at a time. WaitForGcToCompleteLocked(self); + // If someone else beat us to it and changed the collector before we could, exit. + // This is safe to do before the suspend all since we set the collector_type_running_ before + // we exit the loop. If another thread attempts to do the heap transition before we exit, + // then it would get blocked on WaitForGcToCompleteLocked. + if (collector_type == collector_type_) { + return; + } // GC can be disabled if someone has a used GetPrimitiveArrayCritical but not yet released. if (!copying_transition || disable_moving_gc_count_ == 0) { // TODO: Not hard code in semi-space collector? -- cgit v1.1