/usr/share/gocode/src/github.com/sasha-s/go-deadlock/deadlock_test.go is in golang-github-sasha-s-go-deadlock-dev 0.1.0-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | package deadlock
import (
"log"
"math/rand"
"sync"
"sync/atomic"
"testing"
"time"
)
func TestNoDeadlocks(t *testing.T) {
defer restore()()
Opts.DeadlockTimeout = time.Millisecond * 5000
var a RWMutex
var b Mutex
var c RWMutex
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for k := 0; k < 5; k++ {
func() {
a.Lock()
defer a.Unlock()
func() {
b.Lock()
defer b.Unlock()
func() {
c.RLock()
defer c.RUnlock()
time.Sleep(time.Duration((1000 + rand.Intn(1000))) * time.Millisecond / 200)
}()
}()
}()
}
}()
wg.Add(1)
go func() {
defer wg.Done()
for k := 0; k < 5; k++ {
func() {
a.RLock()
defer a.RUnlock()
func() {
b.Lock()
defer b.Unlock()
func() {
c.Lock()
defer c.Unlock()
time.Sleep(time.Duration((1000 + rand.Intn(1000))) * time.Millisecond / 200)
}()
}()
}()
}
}()
}
wg.Wait()
}
func TestLockOrder(t *testing.T) {
defer restore()()
Opts.DeadlockTimeout = 0
var deadlocks uint32
Opts.OnPotentialDeadlock = func() {
atomic.AddUint32(&deadlocks, 1)
}
var a RWMutex
var b Mutex
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
a.Lock()
b.Lock()
b.Unlock()
a.Unlock()
}()
wg.Wait()
wg.Add(1)
go func() {
defer wg.Done()
b.Lock()
a.RLock()
a.RUnlock()
b.Unlock()
}()
wg.Wait()
if deadlocks != 1 {
t.Fatalf("expected 1 deadlock, detected %d", deadlocks)
}
}
func TestHardDeadlock(t *testing.T) {
defer restore()()
Opts.DisableLockOrderDetection = true
Opts.DeadlockTimeout = time.Millisecond * 20
var deadlocks uint32
Opts.OnPotentialDeadlock = func() {
atomic.AddUint32(&deadlocks, 1)
}
var mu Mutex
mu.Lock()
ch := make(chan struct{})
go func() {
defer close(ch)
mu.Lock()
defer mu.Unlock()
}()
select {
case <-ch:
case <-time.After(time.Millisecond * 100):
}
if deadlocks != 1 {
t.Fatalf("expected 1 deadlock, detected %d", deadlocks)
}
log.Println("****************")
mu.Unlock()
}
func restore() func() {
opts := Opts
return func() {
Opts = opts
}
}
|