github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/x/lock.go (about) 1 /* 2 * Copyright 2016-2018 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package x 18 19 import ( 20 "sync" 21 "sync/atomic" 22 ) 23 24 // SafeMutex can be used in place of sync.RWMutex. It allows code to assert 25 // whether the mutex is locked. 26 type SafeMutex struct { 27 m sync.RWMutex 28 // m deadlock.RWMutex // Useful during debugging and testing for detecting locking issues. 29 writer int32 30 readers int32 31 } 32 33 // AlreadyLocked returns true if safe mutex is already being held. 34 func (s *SafeMutex) AlreadyLocked() bool { 35 return atomic.LoadInt32(&s.writer) > 0 36 } 37 38 // Lock locks the safe mutex. 39 func (s *SafeMutex) Lock() { 40 s.m.Lock() 41 AssertTrue(atomic.AddInt32(&s.writer, 1) == 1) 42 } 43 44 // Unlock unlocks the safe mutex. 45 func (s *SafeMutex) Unlock() { 46 AssertTrue(atomic.AddInt32(&s.writer, -1) == 0) 47 s.m.Unlock() 48 } 49 50 // AssertLock asserts whether the lock is being held. 51 func (s *SafeMutex) AssertLock() { 52 AssertTrue(s.AlreadyLocked()) 53 } 54 55 // RLock holds the reader lock. 56 func (s *SafeMutex) RLock() { 57 s.m.RLock() 58 atomic.AddInt32(&s.readers, 1) 59 } 60 61 // RUnlock releases the reader lock. 62 func (s *SafeMutex) RUnlock() { 63 atomic.AddInt32(&s.readers, -1) 64 s.m.RUnlock() 65 } 66 67 // AssertRLock asserts whether the reader lock is being held. 68 func (s *SafeMutex) AssertRLock() { 69 AssertTrue(atomic.LoadInt32(&s.readers) > 0 || 70 atomic.LoadInt32(&s.writer) == 1) 71 }