1
0
mirror of https://github.com/golang/go synced 2024-11-22 02:24:41 -07:00

sync: check Unlock of unlocked Mutex

R=r, adg
CC=golang-dev
https://golang.org/cl/4180044
This commit is contained in:
Russ Cox 2011-02-11 17:47:17 -05:00
parent ca5179d3f6
commit 26880d7e03
2 changed files with 19 additions and 1 deletions

View File

@ -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)
} }

View File

@ -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()
}