ipc/chromium/src/base/thread_collision_warner.cc

changeset 0
6474c204b198
     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

mercurial