1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
import (
"fmt"
"runtime"
"strings"
"sync"
"sync/atomic"
)
func getGID() int64 {
b := make([]byte, 64)
b = b[:runtime.Stack(b, false)]
b = b[:strings.Index(string(b), " ")]
b = b[10:]
var gid int64
fmt.Sscanf(string(b), "%d", &gid)
return gid
}
type RecursiveMutex struct {
sync.Mutex
owner int64
recursion uint32
}
func (rm *RecursiveMutex) Lock() {
gid := getGID()
if atomic.LoadInt64(&rm.owner) == gid {
rm.recursion++
return
}
rm.Mutex.Lock()
atomic.StoreInt64(&rm.owner, gid)
rm.recursion = 1
}
func (rm *RecursiveMutex) UnLock() {
gid := getGID()
if atomic.LoadInt64(&rm.owner) != gid {
panic(fmt.Sprintf("wrong owner(%d): %d!", rm.owner, gid))
}
rm.recursion--
if rm.recursion != 0 {
return
}
atomic.StoreInt64(&rm.owner, -1)
rm.Mutex.Unlock()
}
|