race_checker.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. #ifndef RTC_BASE_RACE_CHECKER_H_
  11. #define RTC_BASE_RACE_CHECKER_H_
  12. #include "rtc_base/checks.h"
  13. #include "rtc_base/platform_thread_types.h"
  14. #include "rtc_base/thread_annotations.h"
  15. namespace rtc {
  16. namespace internal {
  17. class RaceCheckerScope;
  18. } // namespace internal
  19. // Best-effort race-checking implementation. This primitive uses no
  20. // synchronization at all to be as-fast-as-possible in the non-racy case.
  21. class RTC_LOCKABLE RaceChecker {
  22. public:
  23. friend class internal::RaceCheckerScope;
  24. RaceChecker();
  25. private:
  26. bool Acquire() const RTC_EXCLUSIVE_LOCK_FUNCTION();
  27. void Release() const RTC_UNLOCK_FUNCTION();
  28. // Volatile to prevent code being optimized away in Acquire()/Release().
  29. mutable volatile int access_count_ = 0;
  30. mutable volatile PlatformThreadRef accessing_thread_;
  31. };
  32. namespace internal {
  33. class RTC_SCOPED_LOCKABLE RaceCheckerScope {
  34. public:
  35. explicit RaceCheckerScope(const RaceChecker* race_checker)
  36. RTC_EXCLUSIVE_LOCK_FUNCTION(race_checker);
  37. bool RaceDetected() const;
  38. ~RaceCheckerScope() RTC_UNLOCK_FUNCTION();
  39. private:
  40. const RaceChecker* const race_checker_;
  41. const bool race_check_ok_;
  42. };
  43. class RTC_SCOPED_LOCKABLE RaceCheckerScopeDoNothing {
  44. public:
  45. explicit RaceCheckerScopeDoNothing(const RaceChecker* race_checker)
  46. RTC_EXCLUSIVE_LOCK_FUNCTION(race_checker) {}
  47. ~RaceCheckerScopeDoNothing() RTC_UNLOCK_FUNCTION() {}
  48. };
  49. } // namespace internal
  50. } // namespace rtc
  51. #define RTC_CHECK_RUNS_SERIALIZED(x) \
  52. rtc::internal::RaceCheckerScope race_checker(x); \
  53. RTC_CHECK(!race_checker.RaceDetected())
  54. #if RTC_DCHECK_IS_ON
  55. #define RTC_DCHECK_RUNS_SERIALIZED(x) \
  56. rtc::internal::RaceCheckerScope race_checker(x); \
  57. RTC_DCHECK(!race_checker.RaceDetected())
  58. #else
  59. #define RTC_DCHECK_RUNS_SERIALIZED(x) \
  60. rtc::internal::RaceCheckerScopeDoNothing race_checker(x)
  61. #endif
  62. #endif // RTC_BASE_RACE_CHECKER_H_