mirror of
https://github.com/golang/go
synced 2024-11-25 05:07:56 -07:00
sync: check Unlock of unlocked Mutex
R=r, adg CC=golang-dev https://golang.org/cl/4180044
This commit is contained in:
parent
ca5179d3f6
commit
26880d7e03
@ -53,9 +53,14 @@ func (m *Mutex) Lock() {
|
|||||||
// It is allowed for one goroutine to lock a Mutex and then
|
// It is allowed for one goroutine to lock a Mutex and then
|
||||||
// arrange for another goroutine to unlock it.
|
// arrange for another goroutine to unlock it.
|
||||||
func (m *Mutex) Unlock() {
|
func (m *Mutex) Unlock() {
|
||||||
if xadd(&m.key, -1) == 0 {
|
switch v := xadd(&m.key, -1); {
|
||||||
|
case v == 0:
|
||||||
// changed from 1 to 0; no contention
|
// changed from 1 to 0; no contention
|
||||||
return
|
return
|
||||||
|
case int32(v) == -1:
|
||||||
|
// changed from 0 to -1: wasn't locked
|
||||||
|
// (or there are 4 billion goroutines waiting)
|
||||||
|
panic("sync: unlock of unlocked mutex")
|
||||||
}
|
}
|
||||||
runtime.Semrelease(&m.sema)
|
runtime.Semrelease(&m.sema)
|
||||||
}
|
}
|
||||||
|
@ -89,3 +89,16 @@ func BenchmarkContendedMutex(b *testing.B) {
|
|||||||
<-c
|
<-c
|
||||||
<-c
|
<-c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMutexPanic(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if recover() == nil {
|
||||||
|
t.Fatalf("unlock of unlocked mutex did not panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var mu Mutex
|
||||||
|
mu.Lock()
|
||||||
|
mu.Unlock()
|
||||||
|
mu.Unlock()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user