github.com/go-eden/common@v0.1.15-0.20210617133546-059099253264/esync/sync_remutex.go (about) 1 package esync 2 3 import ( 4 "fmt" 5 "github.com/go-eden/common/goid" 6 "sync" 7 "sync/atomic" 8 ) 9 10 // ReMutex Reentrant Mutex 11 type ReMutex struct { 12 sync.Mutex 13 holder int64 14 counter int32 15 } 16 17 func (t *ReMutex) Lock() { 18 var gid = goid.Gid() 19 20 if atomic.LoadInt64(&t.holder) != gid { 21 t.Mutex.Lock() 22 atomic.StoreInt64(&t.holder, gid) 23 t.counter = 1 24 return 25 } 26 27 // relock 28 t.counter++ 29 } 30 31 func (t *ReMutex) Unlock() { 32 var gid = goid.Gid() 33 34 if atomic.LoadInt64(&t.holder) != gid { 35 panic(fmt.Sprintf("Lock conflict, held by g[%v]", t.holder)) 36 } 37 if t.counter > 0 { 38 t.counter-- 39 } 40 if t.counter == 0 { 41 atomic.StoreInt64(&t.holder, 0) 42 t.Mutex.Unlock() 43 } 44 }