• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/race_checker.h"
12 
13 namespace rtc {
14 
RaceChecker()15 RaceChecker::RaceChecker() {}
16 
17 // Note that the implementation here is in itself racy, but we pretend it does
18 // not matter because we want this useful in release builds without having to
19 // pay the cost of using atomics. A race hitting the race checker is likely to
20 // cause access_count_ to diverge from zero and therefore cause the ThreadRef
21 // comparison to fail, signaling a race, although it may not be in the exact
22 // spot where a race *first* appeared in the code we're trying to protect. There
23 // is also a chance that an actual race is missed, however the probability of
24 // that has been considered small enough to be an acceptable trade off.
Acquire() const25 bool RaceChecker::Acquire() const {
26   const PlatformThreadRef current_thread = CurrentThreadRef();
27   // Set new accessing thread if this is a new use.
28   if (access_count_++ == 0)
29     accessing_thread_ = current_thread;
30   // If this is being used concurrently this check will fail for the second
31   // thread entering since it won't set the thread. Recursive use of checked
32   // methods are OK since the accessing thread remains the same.
33   const PlatformThreadRef accessing_thread = accessing_thread_;
34   return IsThreadRefEqual(accessing_thread, current_thread);
35 }
36 
Release() const37 void RaceChecker::Release() const {
38   --access_count_;
39 }
40 
41 namespace internal {
RaceCheckerScope(const RaceChecker * race_checker)42 RaceCheckerScope::RaceCheckerScope(const RaceChecker* race_checker)
43     : race_checker_(race_checker), race_check_ok_(race_checker->Acquire()) {}
44 
RaceDetected() const45 bool RaceCheckerScope::RaceDetected() const {
46   return !race_check_ok_;
47 }
48 
~RaceCheckerScope()49 RaceCheckerScope::~RaceCheckerScope() {
50   race_checker_->Release();
51 }
52 
53 }  // namespace internal
54 }  // namespace rtc
55