github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/tools/checklocks/test/methods.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package test 16 17 import ( 18 "sync" 19 ) 20 21 type testMethods struct { 22 mu sync.Mutex 23 24 // +checklocks:mu 25 guardedField int 26 } 27 28 func (t *testMethods) methodValid() { 29 t.mu.Lock() 30 t.guardedField = 1 31 t.mu.Unlock() 32 } 33 34 func (t *testMethods) methodInvalid() { 35 t.guardedField = 2 // +checklocksfail 36 } 37 38 // +checklocks:t.mu 39 func (t *testMethods) MethodLocked(a, b, c int) { 40 t.guardedField = 3 41 } 42 43 // +checklocksignore 44 func (t *testMethods) methodIgnore() { 45 t.guardedField = 2 46 } 47 48 func testMethodCallsValid(tc *testMethods) { 49 tc.methodValid() 50 } 51 52 func testMethodCallsValidPreconditions(tc *testMethods) { 53 tc.mu.Lock() 54 tc.MethodLocked(1, 2, 3) 55 tc.mu.Unlock() 56 } 57 58 func testMethodCallsInvalid(tc *testMethods) { 59 tc.MethodLocked(4, 5, 6) // +checklocksfail 60 } 61 62 func testMultipleParameters(tc1, tc2, tc3 *testMethods) { 63 tc1.mu.Lock() 64 tc1.guardedField = 1 65 tc2.guardedField = 2 // +checklocksfail 66 tc3.guardedField = 3 // +checklocksfail 67 tc1.mu.Unlock() 68 } 69 70 type testMethodsWithParameters struct { 71 mu sync.Mutex 72 73 // +checklocks:mu 74 guardedField int 75 } 76 77 type ptrToTestMethodsWithParameters *testMethodsWithParameters 78 79 // +checklocks:t.mu 80 // +checklocks:a.mu 81 func (t *testMethodsWithParameters) methodLockedWithParameters(a *testMethodsWithParameters, b *testMethodsWithParameters) { 82 t.guardedField = a.guardedField 83 b.guardedField = a.guardedField // +checklocksfail 84 } 85 86 // +checklocks:t.mu 87 // +checklocks:a.mu 88 // +checklocks:b.mu 89 func (t *testMethodsWithParameters) methodLockedWithPtrType(a *testMethodsWithParameters, b ptrToTestMethodsWithParameters) { 90 t.guardedField = a.guardedField 91 b.guardedField = a.guardedField 92 } 93 94 // +checklocks:a.mu 95 func standaloneFunctionWithGuard(a *testMethodsWithParameters) { 96 a.guardedField = 1 97 a.mu.Unlock() 98 a.guardedField = 1 // +checklocksfail 99 } 100 101 type testMethodsWithEmbedded struct { 102 mu sync.Mutex 103 104 // +checklocks:mu 105 guardedField int 106 p *testMethodsWithParameters 107 } 108 109 // +checklocks:t.mu 110 func (t *testMethodsWithEmbedded) DoLocked(a, b *testMethodsWithParameters) { 111 t.guardedField = 1 112 a.mu.Lock() 113 b.mu.Lock() 114 t.p.methodLockedWithParameters(a, b) // +checklocksfail 115 a.mu.Unlock() 116 b.mu.Unlock() 117 }