| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Based on https://github.com/sasha-s/go-deadlock.
Changes from that package:
Also uses significantly less memory and CPU:
Using this package: BenchmarkLockSingle-24 2716491 444.1 ns/op 32 B/op 1 allocs/op BenchmarkLockParallel-24 2132055 483.0 ns/op 43 B/op 1 allocs/op Using https://github.com/sasha-s/go-deadlock@v0.3.3: BenchmarkLockSingle-24 1000000 1468 ns/op 593 B/op 3 allocs/op BenchmarkLockParallel-24 808564 1313 ns/op 593 B/op 3 allocs/op
go get github.com/linkdata/deadlockThe package enables itself when either the deadlock or race build tag is set, and the nodeadlock build tag is not set. The easiest way is to simply use deadlock.(RW)Mutex and run or test your code with the race detector.
import "github.com/linkdata/deadlock"
var mu deadlock.Mutex
mu.Lock()
defer mu.Unlock()
var rw deadlock.RWMutex
rw.RLock()
defer rw.RUnlock()go run -race .Taking the same lock twice in the same goroutine will deadlock:
A.RLock() // or A.Lock()
...
A.Lock() // or A.RLock()Those cases will be reported immediately when they occur. Also, in case we wait for a lock for more than deadlock.Opts.DeadlockTimeout (30 seconds by default), we also report that as a potential deadlock. Setting the DeadlockTimeout to zero disables this detection.
POTENTIAL DEADLOCK:
goroutine 624 have been trying to lock 0xc0009a20d8 for more than 20ms:
github.com/linkdata/deadlock.(*DeadlockMutex).Lock()
/home/user/src/deadlock/deadlock.go:26 +0x113
github.com/linkdata/deadlock.TestHardDeadlock.func2()
/home/user/src/deadlock/deadlock_test.go:154 +0x92
goroutine 622 previously locked it from:
github.com/linkdata/deadlock.(*DeadlockMutex).Lock()
/home/user/src/deadlock/deadlock.go:26 +0x164
github.com/linkdata/deadlock.TestHardDeadlock()
/home/user/src/deadlock/deadlock_test.go:150 +0xe6
goroutine 622 current stack:
goroutine 622 [sleep]:
time.Sleep(0xf4240)
/usr/local/go/src/runtime/time.go:195 +0x135
github.com/linkdata/deadlock.spinWait(0xc000988340, 0x0?, 0x1)
/home/user/src/deadlock/deadlock_test.go:25 +0x3e
github.com/linkdata/deadlock.TestHardDeadlock(0xc000988340)
/home/user/src/deadlock/deadlock_test.go:157 +0x265
testing.tRunner(0xc000988340, 0x6187e8)
/usr/local/go/src/testing/testing.go:1576 +0x217
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1629 +0x806
One of the most common sources of deadlocks is inconsistent lock ordering. If you have two mutexes A and B, and in one goroutine you have:
A.Lock() // defer A.Unlock() or similar.
...
B.Lock() // defer B.Unlock() or similar.And in another goroutine the order of locks is reversed:
B.Lock() // defer B.Unlock() or similar.
...
A.Lock() // defer A.Unlock() or similar.This does not guarantee a deadlock (maybe the goroutines above can never be running at the same time), but it is bad practice. Detection is enabled by default, but can be disabled by setting deadlock.Opts.MaxMapSize to zero.
POTENTIAL DEADLOCK: Inconsistent locking:
in one goroutine: happened before
github.com/linkdata/deadlock.(*DeadlockRWMutex).Lock()
/home/user/src/deadlock/deadlock.go:55 +0xa8
github.com/linkdata/deadlock.TestLockOrder.func2()
/home/user/src/deadlock/deadlock_test.go:120 +0x34
happened after
github.com/linkdata/deadlock.(*DeadlockMutex).Lock()
/home/user/src/deadlock/deadlock.go:26 +0x11a
github.com/linkdata/deadlock.TestLockOrder.func2()
/home/user/src/deadlock/deadlock_test.go:121 +0xa9
in another goroutine: happened before
github.com/linkdata/deadlock.(*DeadlockMutex).Lock()
/home/user/src/deadlock/deadlock.go:26 +0xa5
github.com/linkdata/deadlock.TestLockOrder.func3()
/home/user/src/deadlock/deadlock_test.go:129 +0x34
happened after
github.com/linkdata/deadlock.(*DeadlockRWMutex).RLock()
/home/user/src/deadlock/deadlock.go:74 +0x11a
github.com/linkdata/deadlock.TestLockOrder.func3()
/home/user/src/deadlock/deadlock_test.go:130 +0xa6
It's often helpful to run extra runtime checks during development and testing, but you don't want to have that code around in a production environment. Since these are constants, if the constant is false, code that depends on it being true gets removed entirely.
We define two:
if deadlock.Debug {
// extra checks or logging go here
}Options are stored in the global variable deadlock.Opts. See Options.
| Back | FazBrowse Home | New Git URL |