From: Rhys Hiltner Date: Thu, 7 Dec 2017 21:38:16 +0000 (-0800) Subject: sync: throw, not panic, for unlock of unlocked mutex X-Git-Tag: go1.10beta2~160 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f72196647e017e834f65dc7264b844e0a2760490;p=gostls13.git 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 TryBot-Result: Gobot Gobot Reviewed-by: Dmitry Vyukov --- diff --git a/src/sync/mutex.go b/src/sync/mutex.go index 1232c629b1..4c5582c809 100644 --- a/src/sync/mutex.go +++ b/src/sync/mutex.go @@ -118,7 +118,7 @@ func (m *Mutex) Lock() { // The goroutine has been woken from sleep, // so we need to reset the flag in either case. if new&mutexWoken == 0 { - panic("sync: inconsistent mutex state") + throw("sync: inconsistent mutex state") } new &^= mutexWoken } @@ -140,7 +140,7 @@ func (m *Mutex) Lock() { // inconsistent state: mutexLocked is not set and we are still // accounted as waiter. Fix that. if old&(mutexLocked|mutexWoken) != 0 || old>>mutexWaiterShift == 0 { - panic("sync: inconsistent mutex state") + throw("sync: inconsistent mutex state") } delta := int32(mutexLocked - 1<>mutexWaiterShift == 1 { @@ -181,7 +181,7 @@ func (m *Mutex) Unlock() { // Fast path: drop lock bit. new := atomic.AddInt32(&m.state, -mutexLocked) if (new+mutexLocked)&mutexLocked == 0 { - panic("sync: unlock of unlocked mutex") + throw("sync: unlock of unlocked mutex") } if new&mutexStarving == 0 { old := new diff --git a/src/sync/mutex_test.go b/src/sync/mutex_test.go index 784471df12..521468439a 100644 --- a/src/sync/mutex_test.go +++ b/src/sync/mutex_test.go @@ -155,7 +155,10 @@ func init() { if len(os.Args) == 3 && os.Args[1] == "TESTMISUSE" { for _, test := range misuseTests { if test.name == os.Args[2] { - test.f() + func() { + defer func() { recover() }() + test.f() + }() fmt.Printf("test completed\n") os.Exit(0) }