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  }