Refactor component/extras into snapshotting
This commit is contained in:
parent
6d9c83c842
commit
6f409be8b2
9 changed files with 81 additions and 79 deletions
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// RLock is like [sync.Mutex], but permits recursive locking.
|
||||
type RLock struct {
|
||||
m sync.Mutex // m is held internally
|
||||
|
||||
|
|
@ -13,32 +14,40 @@ type RLock struct {
|
|||
counter uint64
|
||||
}
|
||||
|
||||
// Lock acquires this lock with the given id, and blocks until it can be aquired.
|
||||
// Concurrent locks with the same ids do not block; however each should be unlocked with a call to unlock.
|
||||
func (rm *RLock) Lock(id int) {
|
||||
loop:
|
||||
for {
|
||||
rm.m.Lock()
|
||||
if !rm.held {
|
||||
switch {
|
||||
case !rm.held:
|
||||
rm.held = true
|
||||
rm.holder = id
|
||||
break
|
||||
} else if rm.held && rm.holder == id {
|
||||
break
|
||||
} else {
|
||||
rm.m.Unlock()
|
||||
time.Sleep(time.Millisecond)
|
||||
continue
|
||||
break loop
|
||||
case rm.held && rm.holder == id:
|
||||
break loop
|
||||
}
|
||||
rm.m.Unlock()
|
||||
time.Sleep(time.Millisecond) // spinning!
|
||||
}
|
||||
|
||||
rm.counter++
|
||||
rm.m.Unlock()
|
||||
}
|
||||
|
||||
// Unlock releases the lock
|
||||
func (rm *RLock) Unlock() {
|
||||
rm.m.Lock()
|
||||
defer rm.m.Unlock()
|
||||
|
||||
if !rm.held || rm.counter <= 0 {
|
||||
panic("RLock: Unlock() without Lock()")
|
||||
}
|
||||
|
||||
rm.counter--
|
||||
if rm.counter == 0 {
|
||||
rm.held = false
|
||||
rm.holder = 0
|
||||
}
|
||||
rm.m.Unlock()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue