@@ -11,18 +11,18 @@ import (
1111)
1212
1313type Mutex struct {
14- mointor
14+ monitor
1515 sync.Mutex
1616}
1717
1818func (m * Mutex ) Lock () {
19- holder , holderStack := m .mointor .wait ()
19+ waitInfo := m .monitor .wait ()
2020 m .Mutex .Lock ()
21- m .mointor .using (holder , holderStack )
21+ m .monitor .using (waitInfo )
2222}
2323
2424func (m * Mutex ) Unlock () {
25- m .mointor .release ()
25+ m .monitor .release ()
2626 m .Mutex .Unlock ()
2727}
2828
@@ -47,61 +47,76 @@ func (rw *RWMutex) RUnlock() {
4747}
4848
4949var (
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' }
5457)
5558
56- type mointor struct {
59+ type monitor struct {
5760 holder int32
5861 holderStack debug.StackInfo
5962}
6063
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 {
6271 globalMutex .Lock ()
6372 defer globalMutex .Unlock ()
6473
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
6876
69- m .verify ([]* mointor {{ holder , holderStack } })
77+ m .verify ([]* waiting { waitInfo })
7078
71- return holder , holderStack
79+ return waitInfo
7280}
7381
74- func (m * mointor ) verify (holderLink []* mointor ) {
82+ func (m * monitor ) verify (waitLink []* waiting ) {
7583 if m .holder != 0 {
7684 // deadlock detected
77- if m .holder == holderLink [0 ].holder {
85+ if m .holder == waitLink [0 ].holder {
7886 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 (" " ))
85100 }
86101 panic (DeadlockError (buf .String ()))
87102 }
88103 // 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 ))
91106 }
92107 }
93108}
94109
95- func (m * mointor ) using (holder int32 , holderStack debug. StackInfo ) {
110+ func (m * monitor ) using (waitInfo * waiting ) {
96111 globalMutex .Lock ()
97112 defer globalMutex .Unlock ()
98113
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
102117}
103118
104- func (m * mointor ) release () {
119+ func (m * monitor ) release () {
105120 m .holder = 0
106121 m .holderStack = nil
107122}
0 commit comments