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:
parent
0a8005c772
commit
dc6726b37f
@ -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.
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user