Commit f7219664 authored by Rhys Hiltner's avatar Rhys Hiltner Committed by Ian Lance Taylor

sync: throw, not panic, for unlock of unlocked mutex

This was originally done in https://golang.org/cl/31359 but partially
undone (apparently unintentionally) in https://golang.org/cl/34310

Fix it, and update tests to ensure the error is unrecoverable.

Fixes #23039

Change-Id: I923ebd613a05e67d8acce77f4a68c64c8574faa6
Reviewed-on: https://go-review.googlesource.com/82656
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarDmitry Vyukov <dvyukov@google.com>
parent 6c877e5d
...@@ -118,7 +118,7 @@ func (m *Mutex) Lock() { ...@@ -118,7 +118,7 @@ func (m *Mutex) Lock() {
// The goroutine has been woken from sleep, // The goroutine has been woken from sleep,
// so we need to reset the flag in either case. // so we need to reset the flag in either case.
if new&mutexWoken == 0 { if new&mutexWoken == 0 {
panic("sync: inconsistent mutex state") throw("sync: inconsistent mutex state")
} }
new &^= mutexWoken new &^= mutexWoken
} }
...@@ -140,7 +140,7 @@ func (m *Mutex) Lock() { ...@@ -140,7 +140,7 @@ func (m *Mutex) Lock() {
// inconsistent state: mutexLocked is not set and we are still // inconsistent state: mutexLocked is not set and we are still
// accounted as waiter. Fix that. // accounted as waiter. Fix that.
if old&(mutexLocked|mutexWoken) != 0 || old>>mutexWaiterShift == 0 { if old&(mutexLocked|mutexWoken) != 0 || old>>mutexWaiterShift == 0 {
panic("sync: inconsistent mutex state") throw("sync: inconsistent mutex state")
} }
delta := int32(mutexLocked - 1<<mutexWaiterShift) delta := int32(mutexLocked - 1<<mutexWaiterShift)
if !starving || old>>mutexWaiterShift == 1 { if !starving || old>>mutexWaiterShift == 1 {
...@@ -181,7 +181,7 @@ func (m *Mutex) Unlock() { ...@@ -181,7 +181,7 @@ func (m *Mutex) Unlock() {
// Fast path: drop lock bit. // Fast path: drop lock bit.
new := atomic.AddInt32(&m.state, -mutexLocked) new := atomic.AddInt32(&m.state, -mutexLocked)
if (new+mutexLocked)&mutexLocked == 0 { if (new+mutexLocked)&mutexLocked == 0 {
panic("sync: unlock of unlocked mutex") throw("sync: unlock of unlocked mutex")
} }
if new&mutexStarving == 0 { if new&mutexStarving == 0 {
old := new old := new
......
...@@ -155,7 +155,10 @@ func init() { ...@@ -155,7 +155,10 @@ func init() {
if len(os.Args) == 3 && os.Args[1] == "TESTMISUSE" { if len(os.Args) == 3 && os.Args[1] == "TESTMISUSE" {
for _, test := range misuseTests { for _, test := range misuseTests {
if test.name == os.Args[2] { if test.name == os.Args[2] {
test.f() func() {
defer func() { recover() }()
test.f()
}()
fmt.Printf("test completed\n") fmt.Printf("test completed\n")
os.Exit(0) os.Exit(0)
} }
......
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