gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/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 // +checklocksignore: Inferred as protected by mu.
   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  }