55 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			55 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 | |
|  *
 | |
|  *  Use of this source code is governed by a BSD-style license
 | |
|  *  that can be found in the LICENSE file in the root of the source
 | |
|  *  tree. An additional intellectual property rights grant can be found
 | |
|  *  in the file PATENTS.  All contributing project authors may
 | |
|  *  be found in the AUTHORS file in the root of the source tree.
 | |
|  */
 | |
| 
 | |
| #include "rtc_base/race_checker.h"
 | |
| 
 | |
| namespace rtc {
 | |
| 
 | |
| RaceChecker::RaceChecker() {}
 | |
| 
 | |
| // Note that the implementation here is in itself racy, but we pretend it does
 | |
| // not matter because we want this useful in release builds without having to
 | |
| // pay the cost of using atomics. A race hitting the race checker is likely to
 | |
| // cause access_count_ to diverge from zero and therefore cause the ThreadRef
 | |
| // comparison to fail, signaling a race, although it may not be in the exact
 | |
| // spot where a race *first* appeared in the code we're trying to protect. There
 | |
| // is also a chance that an actual race is missed, however the probability of
 | |
| // that has been considered small enough to be an acceptable trade off.
 | |
| bool RaceChecker::Acquire() const {
 | |
|   const PlatformThreadRef current_thread = CurrentThreadRef();
 | |
|   // Set new accessing thread if this is a new use.
 | |
|   if (access_count_++ == 0)
 | |
|     accessing_thread_ = current_thread;
 | |
|   // If this is being used concurrently this check will fail for the second
 | |
|   // thread entering since it won't set the thread. Recursive use of checked
 | |
|   // methods are OK since the accessing thread remains the same.
 | |
|   const PlatformThreadRef accessing_thread = accessing_thread_;
 | |
|   return IsThreadRefEqual(accessing_thread, current_thread);
 | |
| }
 | |
| 
 | |
| void RaceChecker::Release() const {
 | |
|   --access_count_;
 | |
| }
 | |
| 
 | |
| namespace internal {
 | |
| RaceCheckerScope::RaceCheckerScope(const RaceChecker* race_checker)
 | |
|     : race_checker_(race_checker), race_check_ok_(race_checker->Acquire()) {}
 | |
| 
 | |
| bool RaceCheckerScope::RaceDetected() const {
 | |
|   return !race_check_ok_;
 | |
| }
 | |
| 
 | |
| RaceCheckerScope::~RaceCheckerScope() {
 | |
|   race_checker_->Release();
 | |
| }
 | |
| 
 | |
| }  // namespace internal
 | |
| }  // namespace rtc
 |