github.com/cs3org/reva/v2@v2.27.7/pkg/storage/utils/sync/mutex.go (about) 1 // Copyright 2018-2022 CERN 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 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package sync 20 21 import ( 22 "sync" 23 ) 24 25 // NamedRWMutex works the same as RWMutex, the only difference is that it stores mutexes in a map and reuses them. 26 // It's handy if you want to write-lock, write-unlock, read-lock and read-unlock for specific names only. 27 type NamedRWMutex struct { 28 pool sync.Pool 29 mus sync.Map 30 } 31 32 // NewNamedRWMutex returns a new instance of NamedRWMutex. 33 func NewNamedRWMutex() NamedRWMutex { 34 return NamedRWMutex{pool: sync.Pool{New: func() interface{} { 35 return new(sync.RWMutex) 36 }}} 37 } 38 39 // Lock locks rw for writing. 40 func (m *NamedRWMutex) Lock(name string) { 41 m.loadOrStore(name).Lock() 42 } 43 44 // Unlock unlocks rw for writing. 45 func (m *NamedRWMutex) Unlock(name string) { 46 m.loadOrStore(name).Unlock() 47 } 48 49 // RLock locks rw for reading. 50 func (m *NamedRWMutex) RLock(name string) { 51 m.loadOrStore(name).RLock() 52 } 53 54 // RUnlock undoes a single RLock call. 55 func (m *NamedRWMutex) RUnlock(name string) { 56 m.loadOrStore(name).RUnlock() 57 } 58 59 func (m *NamedRWMutex) loadOrStore(name string) *sync.RWMutex { 60 pmu := m.pool.Get() 61 mmu, loaded := m.mus.LoadOrStore(name, pmu) 62 if loaded { 63 m.pool.Put(pmu) 64 } 65 66 return mmu.(*sync.RWMutex) 67 }