xref: /aosp_15_r20/external/webrtc/rtc_base/thread_annotations_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 
11 #include "rtc_base/thread_annotations.h"
12 
13 #include "test/gtest.h"
14 
15 namespace {
16 
17 class RTC_LOCKABLE Lock {
18  public:
EnterWrite() const19   void EnterWrite() const RTC_EXCLUSIVE_LOCK_FUNCTION() {}
EnterRead() const20   void EnterRead() const RTC_SHARED_LOCK_FUNCTION() {}
TryEnterWrite() const21   bool TryEnterWrite() const RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
22     return true;
23   }
TryEnterRead() const24   bool TryEnterRead() const RTC_SHARED_TRYLOCK_FUNCTION(true) { return true; }
Leave() const25   void Leave() const RTC_UNLOCK_FUNCTION() {}
26 };
27 
28 class RTC_SCOPED_LOCKABLE ScopeLock {
29  public:
RTC_EXCLUSIVE_LOCK_FUNCTION(lock)30   explicit ScopeLock(const Lock& lock) RTC_EXCLUSIVE_LOCK_FUNCTION(lock) {}
RTC_UNLOCK_FUNCTION()31   ~ScopeLock() RTC_UNLOCK_FUNCTION() {}
32 };
33 
34 class ThreadSafe {
35  public:
ThreadSafe()36   ThreadSafe() { pt_protected_by_lock_ = new int; }
37 
~ThreadSafe()38   ~ThreadSafe() { delete pt_protected_by_lock_; }
39 
LockInOrder()40   void LockInOrder() {
41     beforelock_.EnterWrite();
42     lock_.EnterWrite();
43     pt_lock_.EnterWrite();
44 
45     pt_lock_.Leave();
46     lock_.Leave();
47     beforelock_.Leave();
48   }
49 
UnprotectedFunction()50   void UnprotectedFunction() RTC_LOCKS_EXCLUDED(lock_, pt_lock_) {
51     // Can access unprotected Value.
52     unprotected_ = 15;
53     // Can access pointers themself, but not data they point to.
54     int* tmp = pt_protected_by_lock_;
55     pt_protected_by_lock_ = tmp;
56   }
57 
ReadProtected()58   void ReadProtected() {
59     lock_.EnterRead();
60     unprotected_ = protected_by_lock_;
61     lock_.Leave();
62 
63     if (pt_lock_.TryEnterRead()) {
64       unprotected_ = *pt_protected_by_lock_;
65       pt_lock_.Leave();
66     }
67   }
68 
WriteProtected()69   void WriteProtected() {
70     lock_.EnterWrite();
71     protected_by_lock_ = unprotected_;
72     lock_.Leave();
73 
74     if (pt_lock_.TryEnterWrite()) {
75       *pt_protected_by_lock_ = unprotected_;
76       pt_lock_.Leave();
77     }
78   }
79 
CallReadProtectedFunction()80   void CallReadProtectedFunction() {
81     lock_.EnterRead();
82     pt_lock_.EnterRead();
83     ReadProtectedFunction();
84     pt_lock_.Leave();
85     lock_.Leave();
86   }
87 
CallWriteProtectedFunction()88   void CallWriteProtectedFunction() {
89     ScopeLock scope_lock(GetLock());
90     ScopeLock pt_scope_lock(pt_lock_);
91     WriteProtectedFunction();
92   }
93 
94  private:
ReadProtectedFunction()95   void ReadProtectedFunction() RTC_SHARED_LOCKS_REQUIRED(lock_, pt_lock_) {
96     unprotected_ = protected_by_lock_;
97     unprotected_ = *pt_protected_by_lock_;
98   }
99 
WriteProtectedFunction()100   void WriteProtectedFunction() RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_, pt_lock_) {
101     int x = protected_by_lock_;
102     *pt_protected_by_lock_ = x;
103     protected_by_lock_ = unprotected_;
104   }
105 
GetLock()106   const Lock& GetLock() RTC_LOCK_RETURNED(lock_) { return lock_; }
107 
108   Lock beforelock_ RTC_ACQUIRED_BEFORE(lock_);
109   Lock lock_;
110   Lock pt_lock_ RTC_ACQUIRED_AFTER(lock_);
111 
112   int unprotected_ = 0;
113 
114   int protected_by_lock_ RTC_GUARDED_BY(lock_) = 0;
115 
116   int* pt_protected_by_lock_ RTC_PT_GUARDED_BY(pt_lock_);
117 };
118 
119 }  // namespace
120 
TEST(ThreadAnnotationsTest,Test)121 TEST(ThreadAnnotationsTest, Test) {
122   // This test ensure thread annotations doesn't break compilation.
123   // Thus no run-time expectations.
124   ThreadSafe t;
125   t.LockInOrder();
126   t.UnprotectedFunction();
127   t.ReadProtected();
128   t.WriteProtected();
129   t.CallReadProtectedFunction();
130   t.CallWriteProtectedFunction();
131 }
132