aboutsummaryrefslogtreecommitdiff
path: root/src/sync
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-11-13 14:36:35 -0800
committerIan Lance Taylor <iant@golang.org>2021-11-16 05:58:03 +0000
commitfdd67930a0f2fec891e4be9c2b62996eb8b06ce5 (patch)
tree89337602ac14ed68ae57f47fb05b5798640cacdf /src/sync
parent865689571d52fee0b4c910d54bd4ba1484ff2344 (diff)
downloadgo-fdd67930a0f2fec891e4be9c2b62996eb8b06ce5.tar.xz
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 <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/sync')
-rw-r--r--src/sync/mutex.go21
1 files changed, 15 insertions, 6 deletions
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() {