From: Ian Lance Taylor Date: Sat, 13 Nov 2021 22:36:35 +0000 (-0800) Subject: sync: in TryLock try to acquire mutex even if state is not 0 X-Git-Tag: go1.18beta1~307 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=fdd67930a0f2fec891e4be9c2b62996eb8b06ce5;p=gostls13.git sync: in TryLock try to acquire mutex even if state is not 0 For #45435 Change-Id: I728accd9a53c1826243f52aa04dc2a0a1dfdaadf Reviewed-on: https://go-review.googlesource.com/c/go/+/363672 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Reviewed-by: Dmitry Vyukov --- diff --git a/src/sync/mutex.go b/src/sync/mutex.go index 9dd04d9470..18b2cedba7 100644 --- a/src/sync/mutex.go +++ b/src/sync/mutex.go @@ -87,13 +87,22 @@ func (m *Mutex) Lock() { // and use of TryLock is often a sign of a deeper problem // in a particular use of mutexes. func (m *Mutex) TryLock() bool { - if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) { - if race.Enabled { - race.Acquire(unsafe.Pointer(m)) - } - return true + old := m.state + if old&(mutexLocked|mutexStarving) != 0 { + return false + } + + // There may be a goroutine waiting for the mutex, but we are + // running now and can try to grab the mutex before that + // goroutine wakes up. + if !atomic.CompareAndSwapInt32(&m.state, old, old|mutexLocked) { + return false + } + + if race.Enabled { + race.Acquire(unsafe.Pointer(m)) } - return false + return true } func (m *Mutex) lockSlow() {