mirror of
https://github.com/tursom/GoCollections.git
synced 2025-02-26 20:20:31 +08:00
55 lines
942 B
Go
55 lines
942 B
Go
package concurrent
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/tursom/GoCollections/exceptions"
|
|
"sync"
|
|
)
|
|
|
|
type ReentrantLock struct {
|
|
lock sync.Mutex
|
|
cond sync.Cond
|
|
recursion int32
|
|
host int64
|
|
}
|
|
|
|
func NewReentrantLock() *ReentrantLock {
|
|
res := &ReentrantLock{
|
|
recursion: 0,
|
|
host: 0,
|
|
}
|
|
res.cond = *sync.NewCond(&res.lock)
|
|
return res
|
|
}
|
|
|
|
func (rt *ReentrantLock) Lock() {
|
|
id := GetGoroutineID()
|
|
rt.lock.Lock()
|
|
defer rt.lock.Unlock()
|
|
|
|
if rt.host == id {
|
|
rt.recursion++
|
|
return
|
|
}
|
|
|
|
for rt.recursion != 0 {
|
|
rt.cond.Wait()
|
|
}
|
|
rt.host = id
|
|
rt.recursion = 1
|
|
}
|
|
|
|
func (rt *ReentrantLock) Unlock() {
|
|
rt.lock.Lock()
|
|
defer rt.lock.Unlock()
|
|
|
|
if rt.recursion == 0 || rt.host != GetGoroutineID() {
|
|
panic(exceptions.NewWrongCallHostException(fmt.Sprintf("the wrong call host: (%d); current_id: %d; recursion: %d", rt.host, GetGoroutineID(), rt.recursion)))
|
|
}
|
|
|
|
rt.recursion--
|
|
if rt.recursion == 0 {
|
|
rt.cond.Signal()
|
|
}
|
|
}
|