1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/thread_collision_warner.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,64 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/thread_collision_warner.h" 1.9 + 1.10 +#include "base/logging.h" 1.11 +#include "base/platform_thread.h" 1.12 + 1.13 +namespace base { 1.14 + 1.15 +void DCheckAsserter::warn() { 1.16 + NOTREACHED() << "Thread Collision"; 1.17 +} 1.18 + 1.19 +static subtle::Atomic32 CurrentThread() { 1.20 + const PlatformThreadId current_thread_id = PlatformThread::CurrentId(); 1.21 + // We need to get the thread id into an atomic data type. This might be a 1.22 + // truncating conversion, but any loss-of-information just increases the 1.23 + // chance of a fault negative, not a false positive. 1.24 + const subtle::Atomic32 atomic_thread_id = 1.25 + static_cast<subtle::Atomic32>(current_thread_id); 1.26 + 1.27 + return atomic_thread_id; 1.28 +} 1.29 + 1.30 +void ThreadCollisionWarner::EnterSelf() { 1.31 + // If the active thread is 0 then I'll write the current thread ID 1.32 + // if two or more threads arrive here only one will succeed to 1.33 + // write on valid_thread_id_ the current thread ID. 1.34 + subtle::Atomic32 current_thread_id = CurrentThread(); 1.35 + 1.36 + int previous_value = subtle::NoBarrier_CompareAndSwap(&valid_thread_id_, 1.37 + 0, 1.38 + current_thread_id); 1.39 + if (previous_value != 0 && previous_value != current_thread_id) { 1.40 + // gotcha! a thread is trying to use the same class and that is 1.41 + // not current thread. 1.42 + asserter_->warn(); 1.43 + } 1.44 + 1.45 + subtle::NoBarrier_AtomicIncrement(&counter_, 1); 1.46 +} 1.47 + 1.48 +void ThreadCollisionWarner::Enter() { 1.49 + subtle::Atomic32 current_thread_id = CurrentThread(); 1.50 + 1.51 + if (subtle::NoBarrier_CompareAndSwap(&valid_thread_id_, 1.52 + 0, 1.53 + current_thread_id) != 0) { 1.54 + // gotcha! another thread is trying to use the same class. 1.55 + asserter_->warn(); 1.56 + } 1.57 + 1.58 + subtle::NoBarrier_AtomicIncrement(&counter_, 1); 1.59 +} 1.60 + 1.61 +void ThreadCollisionWarner::Leave() { 1.62 + if (subtle::Barrier_AtomicIncrement(&counter_, -1) == 0) { 1.63 + subtle::NoBarrier_Store(&valid_thread_id_, 0); 1.64 + } 1.65 +} 1.66 + 1.67 +} // namespace base