summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/rtc_base/race_checker.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/rtc_base/race_checker.h')
-rw-r--r--third_party/libwebrtc/rtc_base/race_checker.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/race_checker.h b/third_party/libwebrtc/rtc_base/race_checker.h
new file mode 100644
index 0000000000..00bab52f33
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/race_checker.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#ifndef RTC_BASE_RACE_CHECKER_H_
+#define RTC_BASE_RACE_CHECKER_H_
+
+#include "rtc_base/checks.h"
+#include "rtc_base/platform_thread_types.h"
+#include "rtc_base/thread_annotations.h"
+
+namespace rtc {
+
+namespace internal {
+class RaceCheckerScope;
+} // namespace internal
+
+// Best-effort race-checking implementation. This primitive uses no
+// synchronization at all to be as-fast-as-possible in the non-racy case.
+class RTC_LOCKABLE RaceChecker {
+ public:
+ friend class internal::RaceCheckerScope;
+ RaceChecker();
+
+ private:
+ bool Acquire() const RTC_EXCLUSIVE_LOCK_FUNCTION();
+ void Release() const RTC_UNLOCK_FUNCTION();
+
+ // Volatile to prevent code being optimized away in Acquire()/Release().
+ mutable volatile int access_count_ = 0;
+ mutable volatile PlatformThreadRef accessing_thread_;
+};
+
+namespace internal {
+class RTC_SCOPED_LOCKABLE RaceCheckerScope {
+ public:
+ explicit RaceCheckerScope(const RaceChecker* race_checker)
+ RTC_EXCLUSIVE_LOCK_FUNCTION(race_checker);
+
+ bool RaceDetected() const;
+ ~RaceCheckerScope() RTC_UNLOCK_FUNCTION();
+
+ private:
+ const RaceChecker* const race_checker_;
+ const bool race_check_ok_;
+};
+
+class RTC_SCOPED_LOCKABLE RaceCheckerScopeDoNothing {
+ public:
+ explicit RaceCheckerScopeDoNothing(const RaceChecker* race_checker)
+ RTC_EXCLUSIVE_LOCK_FUNCTION(race_checker) {}
+
+ ~RaceCheckerScopeDoNothing() RTC_UNLOCK_FUNCTION() {}
+};
+
+} // namespace internal
+} // namespace rtc
+
+#define RTC_CHECK_RUNS_SERIALIZED(x) RTC_CHECK_RUNS_SERIALIZED_NEXT(x, __LINE__)
+
+#define RTC_CHECK_RUNS_SERIALIZED_NEXT(x, suffix) \
+ RTC_CHECK_RUNS_SERIALIZED_IMPL(x, suffix)
+
+#define RTC_CHECK_RUNS_SERIALIZED_IMPL(x, suffix) \
+ rtc::internal::RaceCheckerScope race_checker##suffix(x); \
+ RTC_CHECK(!race_checker##suffix.RaceDetected())
+
+#if RTC_DCHECK_IS_ON
+#define RTC_DCHECK_RUNS_SERIALIZED(x) \
+ rtc::internal::RaceCheckerScope race_checker(x); \
+ RTC_DCHECK(!race_checker.RaceDetected())
+#else
+#define RTC_DCHECK_RUNS_SERIALIZED(x) \
+ rtc::internal::RaceCheckerScopeDoNothing race_checker(x)
+#endif
+
+#endif // RTC_BASE_RACE_CHECKER_H_