xref: /aosp_15_r20/external/webrtc/rtc_base/thread_annotations_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker namespace {
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker class RTC_LOCKABLE Lock {
18*d9f75844SAndroid Build Coastguard Worker  public:
EnterWrite() const19*d9f75844SAndroid Build Coastguard Worker   void EnterWrite() const RTC_EXCLUSIVE_LOCK_FUNCTION() {}
EnterRead() const20*d9f75844SAndroid Build Coastguard Worker   void EnterRead() const RTC_SHARED_LOCK_FUNCTION() {}
TryEnterWrite() const21*d9f75844SAndroid Build Coastguard Worker   bool TryEnterWrite() const RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
22*d9f75844SAndroid Build Coastguard Worker     return true;
23*d9f75844SAndroid Build Coastguard Worker   }
TryEnterRead() const24*d9f75844SAndroid Build Coastguard Worker   bool TryEnterRead() const RTC_SHARED_TRYLOCK_FUNCTION(true) { return true; }
Leave() const25*d9f75844SAndroid Build Coastguard Worker   void Leave() const RTC_UNLOCK_FUNCTION() {}
26*d9f75844SAndroid Build Coastguard Worker };
27*d9f75844SAndroid Build Coastguard Worker 
28*d9f75844SAndroid Build Coastguard Worker class RTC_SCOPED_LOCKABLE ScopeLock {
29*d9f75844SAndroid Build Coastguard Worker  public:
RTC_EXCLUSIVE_LOCK_FUNCTION(lock)30*d9f75844SAndroid Build Coastguard Worker   explicit ScopeLock(const Lock& lock) RTC_EXCLUSIVE_LOCK_FUNCTION(lock) {}
RTC_UNLOCK_FUNCTION()31*d9f75844SAndroid Build Coastguard Worker   ~ScopeLock() RTC_UNLOCK_FUNCTION() {}
32*d9f75844SAndroid Build Coastguard Worker };
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker class ThreadSafe {
35*d9f75844SAndroid Build Coastguard Worker  public:
ThreadSafe()36*d9f75844SAndroid Build Coastguard Worker   ThreadSafe() { pt_protected_by_lock_ = new int; }
37*d9f75844SAndroid Build Coastguard Worker 
~ThreadSafe()38*d9f75844SAndroid Build Coastguard Worker   ~ThreadSafe() { delete pt_protected_by_lock_; }
39*d9f75844SAndroid Build Coastguard Worker 
LockInOrder()40*d9f75844SAndroid Build Coastguard Worker   void LockInOrder() {
41*d9f75844SAndroid Build Coastguard Worker     beforelock_.EnterWrite();
42*d9f75844SAndroid Build Coastguard Worker     lock_.EnterWrite();
43*d9f75844SAndroid Build Coastguard Worker     pt_lock_.EnterWrite();
44*d9f75844SAndroid Build Coastguard Worker 
45*d9f75844SAndroid Build Coastguard Worker     pt_lock_.Leave();
46*d9f75844SAndroid Build Coastguard Worker     lock_.Leave();
47*d9f75844SAndroid Build Coastguard Worker     beforelock_.Leave();
48*d9f75844SAndroid Build Coastguard Worker   }
49*d9f75844SAndroid Build Coastguard Worker 
UnprotectedFunction()50*d9f75844SAndroid Build Coastguard Worker   void UnprotectedFunction() RTC_LOCKS_EXCLUDED(lock_, pt_lock_) {
51*d9f75844SAndroid Build Coastguard Worker     // Can access unprotected Value.
52*d9f75844SAndroid Build Coastguard Worker     unprotected_ = 15;
53*d9f75844SAndroid Build Coastguard Worker     // Can access pointers themself, but not data they point to.
54*d9f75844SAndroid Build Coastguard Worker     int* tmp = pt_protected_by_lock_;
55*d9f75844SAndroid Build Coastguard Worker     pt_protected_by_lock_ = tmp;
56*d9f75844SAndroid Build Coastguard Worker   }
57*d9f75844SAndroid Build Coastguard Worker 
ReadProtected()58*d9f75844SAndroid Build Coastguard Worker   void ReadProtected() {
59*d9f75844SAndroid Build Coastguard Worker     lock_.EnterRead();
60*d9f75844SAndroid Build Coastguard Worker     unprotected_ = protected_by_lock_;
61*d9f75844SAndroid Build Coastguard Worker     lock_.Leave();
62*d9f75844SAndroid Build Coastguard Worker 
63*d9f75844SAndroid Build Coastguard Worker     if (pt_lock_.TryEnterRead()) {
64*d9f75844SAndroid Build Coastguard Worker       unprotected_ = *pt_protected_by_lock_;
65*d9f75844SAndroid Build Coastguard Worker       pt_lock_.Leave();
66*d9f75844SAndroid Build Coastguard Worker     }
67*d9f75844SAndroid Build Coastguard Worker   }
68*d9f75844SAndroid Build Coastguard Worker 
WriteProtected()69*d9f75844SAndroid Build Coastguard Worker   void WriteProtected() {
70*d9f75844SAndroid Build Coastguard Worker     lock_.EnterWrite();
71*d9f75844SAndroid Build Coastguard Worker     protected_by_lock_ = unprotected_;
72*d9f75844SAndroid Build Coastguard Worker     lock_.Leave();
73*d9f75844SAndroid Build Coastguard Worker 
74*d9f75844SAndroid Build Coastguard Worker     if (pt_lock_.TryEnterWrite()) {
75*d9f75844SAndroid Build Coastguard Worker       *pt_protected_by_lock_ = unprotected_;
76*d9f75844SAndroid Build Coastguard Worker       pt_lock_.Leave();
77*d9f75844SAndroid Build Coastguard Worker     }
78*d9f75844SAndroid Build Coastguard Worker   }
79*d9f75844SAndroid Build Coastguard Worker 
CallReadProtectedFunction()80*d9f75844SAndroid Build Coastguard Worker   void CallReadProtectedFunction() {
81*d9f75844SAndroid Build Coastguard Worker     lock_.EnterRead();
82*d9f75844SAndroid Build Coastguard Worker     pt_lock_.EnterRead();
83*d9f75844SAndroid Build Coastguard Worker     ReadProtectedFunction();
84*d9f75844SAndroid Build Coastguard Worker     pt_lock_.Leave();
85*d9f75844SAndroid Build Coastguard Worker     lock_.Leave();
86*d9f75844SAndroid Build Coastguard Worker   }
87*d9f75844SAndroid Build Coastguard Worker 
CallWriteProtectedFunction()88*d9f75844SAndroid Build Coastguard Worker   void CallWriteProtectedFunction() {
89*d9f75844SAndroid Build Coastguard Worker     ScopeLock scope_lock(GetLock());
90*d9f75844SAndroid Build Coastguard Worker     ScopeLock pt_scope_lock(pt_lock_);
91*d9f75844SAndroid Build Coastguard Worker     WriteProtectedFunction();
92*d9f75844SAndroid Build Coastguard Worker   }
93*d9f75844SAndroid Build Coastguard Worker 
94*d9f75844SAndroid Build Coastguard Worker  private:
ReadProtectedFunction()95*d9f75844SAndroid Build Coastguard Worker   void ReadProtectedFunction() RTC_SHARED_LOCKS_REQUIRED(lock_, pt_lock_) {
96*d9f75844SAndroid Build Coastguard Worker     unprotected_ = protected_by_lock_;
97*d9f75844SAndroid Build Coastguard Worker     unprotected_ = *pt_protected_by_lock_;
98*d9f75844SAndroid Build Coastguard Worker   }
99*d9f75844SAndroid Build Coastguard Worker 
WriteProtectedFunction()100*d9f75844SAndroid Build Coastguard Worker   void WriteProtectedFunction() RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_, pt_lock_) {
101*d9f75844SAndroid Build Coastguard Worker     int x = protected_by_lock_;
102*d9f75844SAndroid Build Coastguard Worker     *pt_protected_by_lock_ = x;
103*d9f75844SAndroid Build Coastguard Worker     protected_by_lock_ = unprotected_;
104*d9f75844SAndroid Build Coastguard Worker   }
105*d9f75844SAndroid Build Coastguard Worker 
GetLock()106*d9f75844SAndroid Build Coastguard Worker   const Lock& GetLock() RTC_LOCK_RETURNED(lock_) { return lock_; }
107*d9f75844SAndroid Build Coastguard Worker 
108*d9f75844SAndroid Build Coastguard Worker   Lock beforelock_ RTC_ACQUIRED_BEFORE(lock_);
109*d9f75844SAndroid Build Coastguard Worker   Lock lock_;
110*d9f75844SAndroid Build Coastguard Worker   Lock pt_lock_ RTC_ACQUIRED_AFTER(lock_);
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   int unprotected_ = 0;
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker   int protected_by_lock_ RTC_GUARDED_BY(lock_) = 0;
115*d9f75844SAndroid Build Coastguard Worker 
116*d9f75844SAndroid Build Coastguard Worker   int* pt_protected_by_lock_ RTC_PT_GUARDED_BY(pt_lock_);
117*d9f75844SAndroid Build Coastguard Worker };
118*d9f75844SAndroid Build Coastguard Worker 
119*d9f75844SAndroid Build Coastguard Worker }  // namespace
120*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadAnnotationsTest,Test)121*d9f75844SAndroid Build Coastguard Worker TEST(ThreadAnnotationsTest, Test) {
122*d9f75844SAndroid Build Coastguard Worker   // This test ensure thread annotations doesn't break compilation.
123*d9f75844SAndroid Build Coastguard Worker   // Thus no run-time expectations.
124*d9f75844SAndroid Build Coastguard Worker   ThreadSafe t;
125*d9f75844SAndroid Build Coastguard Worker   t.LockInOrder();
126*d9f75844SAndroid Build Coastguard Worker   t.UnprotectedFunction();
127*d9f75844SAndroid Build Coastguard Worker   t.ReadProtected();
128*d9f75844SAndroid Build Coastguard Worker   t.WriteProtected();
129*d9f75844SAndroid Build Coastguard Worker   t.CallReadProtectedFunction();
130*d9f75844SAndroid Build Coastguard Worker   t.CallWriteProtectedFunction();
131*d9f75844SAndroid Build Coastguard Worker }
132