github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/tcpip/stack/route_stack_mutex.go (about) 1 package stack 2 3 import ( 4 "reflect" 5 6 "github.com/sagernet/gvisor/pkg/sync" 7 "github.com/sagernet/gvisor/pkg/sync/locking" 8 ) 9 10 // RWMutex is sync.RWMutex with the correctness validator. 11 type routeStackRWMutex struct { 12 mu sync.RWMutex 13 } 14 15 // lockNames is a list of user-friendly lock names. 16 // Populated in init. 17 var routeStacklockNames []string 18 19 // lockNameIndex is used as an index passed to NestedLock and NestedUnlock, 20 // referring to an index within lockNames. 21 // Values are specified using the "consts" field of go_template_instance. 22 type routeStacklockNameIndex int 23 24 // DO NOT REMOVE: The following function automatically replaced with lock index constants. 25 // LOCK_NAME_INDEX_CONSTANTS 26 const () 27 28 // Lock locks m. 29 // +checklocksignore 30 func (m *routeStackRWMutex) Lock() { 31 locking.AddGLock(routeStackprefixIndex, -1) 32 m.mu.Lock() 33 } 34 35 // NestedLock locks m knowing that another lock of the same type is held. 36 // +checklocksignore 37 func (m *routeStackRWMutex) NestedLock(i routeStacklockNameIndex) { 38 locking.AddGLock(routeStackprefixIndex, int(i)) 39 m.mu.Lock() 40 } 41 42 // Unlock unlocks m. 43 // +checklocksignore 44 func (m *routeStackRWMutex) Unlock() { 45 m.mu.Unlock() 46 locking.DelGLock(routeStackprefixIndex, -1) 47 } 48 49 // NestedUnlock unlocks m knowing that another lock of the same type is held. 50 // +checklocksignore 51 func (m *routeStackRWMutex) NestedUnlock(i routeStacklockNameIndex) { 52 m.mu.Unlock() 53 locking.DelGLock(routeStackprefixIndex, int(i)) 54 } 55 56 // RLock locks m for reading. 57 // +checklocksignore 58 func (m *routeStackRWMutex) RLock() { 59 locking.AddGLock(routeStackprefixIndex, -1) 60 m.mu.RLock() 61 } 62 63 // RUnlock undoes a single RLock call. 64 // +checklocksignore 65 func (m *routeStackRWMutex) RUnlock() { 66 m.mu.RUnlock() 67 locking.DelGLock(routeStackprefixIndex, -1) 68 } 69 70 // RLockBypass locks m for reading without executing the validator. 71 // +checklocksignore 72 func (m *routeStackRWMutex) RLockBypass() { 73 m.mu.RLock() 74 } 75 76 // RUnlockBypass undoes a single RLockBypass call. 77 // +checklocksignore 78 func (m *routeStackRWMutex) RUnlockBypass() { 79 m.mu.RUnlock() 80 } 81 82 // DowngradeLock atomically unlocks rw for writing and locks it for reading. 83 // +checklocksignore 84 func (m *routeStackRWMutex) DowngradeLock() { 85 m.mu.DowngradeLock() 86 } 87 88 var routeStackprefixIndex *locking.MutexClass 89 90 // DO NOT REMOVE: The following function is automatically replaced. 91 func routeStackinitLockNames() {} 92 93 func init() { 94 routeStackinitLockNames() 95 routeStackprefixIndex = locking.NewMutexClass(reflect.TypeOf(routeStackRWMutex{}), routeStacklockNames) 96 }