diff options
Diffstat (limited to 'third_party/libwebrtc/rtc_base/race_checker.cc')
-rw-r--r-- | third_party/libwebrtc/rtc_base/race_checker.cc | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/race_checker.cc b/third_party/libwebrtc/rtc_base/race_checker.cc new file mode 100644 index 0000000000..f0d4e868c2 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/race_checker.cc @@ -0,0 +1,56 @@ +/* + * 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. + const int current_access_count = access_count_; + access_count_ = access_count_ + 1; + if (current_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_ = access_count_ - 1; +} + +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 |