@@ -11,18 +11,18 @@ import (
11
11
)
12
12
13
13
type Mutex struct {
14
- mointor
14
+ monitor
15
15
sync.Mutex
16
16
}
17
17
18
18
func (m * Mutex ) Lock () {
19
- holder , holderStack := m .mointor .wait ()
19
+ waitInfo := m .monitor .wait ()
20
20
m .Mutex .Lock ()
21
- m .mointor .using (holder , holderStack )
21
+ m .monitor .using (waitInfo )
22
22
}
23
23
24
24
func (m * Mutex ) Unlock () {
25
- m .mointor .release ()
25
+ m .monitor .release ()
26
26
m .Mutex .Unlock ()
27
27
}
28
28
@@ -47,61 +47,76 @@ func (rw *RWMutex) RUnlock() {
47
47
}
48
48
49
49
var (
50
- globalMutex = new (sync.Mutex )
51
- waitTargets = make (map [int32 ]* mointor )
52
- goroutineBegin = []byte ("goroutine " )
53
- newline = []byte {'\n' }
50
+ globalMutex = new (sync.Mutex )
51
+ waitingList = make (map [int32 ]* waiting )
52
+ titleStr = []byte ("[DEAD LOCK]\n " )
53
+ goStr = []byte ("goroutine " )
54
+ waitStr = []byte (" wait" )
55
+ holdStr = []byte (" hold" )
56
+ lineStr = []byte {'\n' }
54
57
)
55
58
56
- type mointor struct {
59
+ type monitor struct {
57
60
holder int32
58
61
holderStack debug.StackInfo
59
62
}
60
63
61
- func (m * mointor ) wait () (int32 , debug.StackInfo ) {
64
+ type waiting struct {
65
+ monitor * monitor
66
+ holder int32
67
+ holderStack debug.StackInfo
68
+ }
69
+
70
+ func (m * monitor ) wait () * waiting {
62
71
globalMutex .Lock ()
63
72
defer globalMutex .Unlock ()
64
73
65
- holder := goid .Get ()
66
- holderStack := debug .StackTrace (3 , 0 )
67
- waitTargets [holder ] = m
74
+ waitInfo := & waiting {m , goid .Get (), debug .StackTrace (3 , 0 )}
75
+ waitingList [waitInfo .holder ] = waitInfo
68
76
69
- m .verify ([]* mointor {{ holder , holderStack } })
77
+ m .verify ([]* waiting { waitInfo })
70
78
71
- return holder , holderStack
79
+ return waitInfo
72
80
}
73
81
74
- func (m * mointor ) verify (holderLink []* mointor ) {
82
+ func (m * monitor ) verify (waitLink []* waiting ) {
75
83
if m .holder != 0 {
76
84
// deadlock detected
77
- if m .holder == holderLink [0 ].holder {
85
+ if m .holder == waitLink [0 ].holder {
78
86
buf := new (bytes.Buffer )
79
- buf .WriteString ("[DEAD LOCK]\n " )
80
- for i := 0 ; i < len (holderLink ); i ++ {
81
- buf .Write (goroutineBegin )
82
- buf .WriteString (strconv .Itoa (int (holderLink [i ].holder )))
83
- buf .Write (newline )
84
- buf .Write (holderLink [i ].holderStack .Bytes (" " ))
87
+ buf .Write (titleStr )
88
+ for i := 0 ; i < len (waitLink ); i ++ {
89
+ buf .Write (goStr )
90
+ buf .WriteString (strconv .Itoa (int (waitLink [i ].holder )))
91
+ buf .Write (waitStr )
92
+ buf .Write (lineStr )
93
+ buf .Write (waitLink [i ].holderStack .Bytes (" " ))
94
+
95
+ buf .Write (goStr )
96
+ buf .WriteString (strconv .Itoa (int (waitLink [i ].monitor .holder )))
97
+ buf .Write (holdStr )
98
+ buf .Write (lineStr )
99
+ buf .Write (waitLink [i ].monitor .holderStack .Bytes (" " ))
85
100
}
86
101
panic (DeadlockError (buf .String ()))
87
102
}
88
103
// the lock holder is waiting for another lock
89
- if waitTarget , exists := waitTargets [m .holder ]; exists {
90
- waitTarget . verify (append (holderLink , m ))
104
+ if waitInfo , exists := waitingList [m .holder ]; exists {
105
+ waitInfo . monitor . verify (append (waitLink , waitInfo ))
91
106
}
92
107
}
93
108
}
94
109
95
- func (m * mointor ) using (holder int32 , holderStack debug. StackInfo ) {
110
+ func (m * monitor ) using (waitInfo * waiting ) {
96
111
globalMutex .Lock ()
97
112
defer globalMutex .Unlock ()
98
113
99
- delete (waitTargets , holder )
100
- m .holder = holder
101
- m .holderStack = holderStack
114
+ delete (waitingList , waitInfo . holder )
115
+ m .holder = waitInfo . holder
116
+ m .holderStack = waitInfo . holderStack
102
117
}
103
118
104
- func (m * mointor ) release () {
119
+ func (m * monitor ) release () {
105
120
m .holder = 0
106
121
m .holderStack = nil
107
122
}
0 commit comments