1
0
mirror of https://github.com/golang/go synced 2024-11-25 08:47:56 -07:00

runtime: fix timers crash

Timer callbacks occasionally crash
with "sched while holding locks" message.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5381043
This commit is contained in:
Dmitriy Vyukov 2011-11-14 21:59:48 +03:00
parent 0a8005c772
commit dc6726b37f
2 changed files with 23 additions and 1 deletions

View File

@ -149,6 +149,8 @@ timerproc(void)
{ {
int64 delta, now; int64 delta, now;
Timer *t; Timer *t;
void (*f)(int64, Eface);
Eface arg;
for(;;) { for(;;) {
runtime·lock(&timers); runtime·lock(&timers);
@ -173,7 +175,11 @@ timerproc(void)
siftdown(0); siftdown(0);
t->i = -1; // mark as removed t->i = -1; // mark as removed
} }
t->f(now, t->arg); f = t->f;
arg = t->arg;
runtime·unlock(&timers);
f(now, arg);
runtime·lock(&timers);
} }
if(delta < 0) { if(delta < 0) {
// No timers left - put goroutine to sleep. // No timers left - put goroutine to sleep.

View File

@ -7,7 +7,9 @@ package time_test
import ( import (
"errors" "errors"
"fmt" "fmt"
"runtime"
"sort" "sort"
"sync/atomic"
"testing" "testing"
. "time" . "time"
) )
@ -47,6 +49,20 @@ func TestAfterFunc(t *testing.T) {
<-c <-c
} }
func TestAfterStress(t *testing.T) {
stop := uint32(0)
go func() {
for atomic.LoadUint32(&stop) == 0 {
runtime.GC()
}
}()
c := Tick(1)
for i := 0; i < 100; i++ {
<-c
}
atomic.StoreUint32(&stop, 1)
}
func BenchmarkAfterFunc(b *testing.B) { func BenchmarkAfterFunc(b *testing.B) {
i := b.N i := b.N
c := make(chan bool) c := make(chan bool)