Commit 26880d7e authored by Russ Cox's avatar Russ Cox

sync: check Unlock of unlocked Mutex

R=r, adg
CC=golang-dev
https://golang.org/cl/4180044
parent ca5179d3
...@@ -53,9 +53,14 @@ func (m *Mutex) Lock() { ...@@ -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) { ...@@ -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()
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment