mirror of
https://github.com/golang/go
synced 2024-11-21 14:54:40 -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
|
||||
// arrange for another goroutine to unlock it.
|
||||
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
|
||||
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)
|
||||
}
|
||||
|
@ -89,3 +89,16 @@ func BenchmarkContendedMutex(b *testing.B) {
|
||||
<-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