1
0
mirror of https://github.com/golang/go synced 2024-11-19 20:54:39 -07:00

runtime: fix program termination when main goroutine calls Goexit

Do not consider idle finalizer/bgsweep/timer goroutines as doing something useful.
We can't simply set isbackground for the whole lifetime of the goroutines,
because when finalizer goroutine calls user function, we do want to consider it
as doing something useful.
This is borken due to timers for quite some time.
With background sweep is become even more broken.
Fixes #7784.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/87960044
This commit is contained in:
Dmitriy Vyukov 2014-04-15 19:48:17 +04:00
parent d826b2ed98
commit 55e0f36fb4
3 changed files with 34 additions and 0 deletions

View File

@ -144,6 +144,15 @@ panic: again
}
func TestGoexitExit(t *testing.T) {
output := executeTest(t, goexitExitSource, nil)
want := ""
if output != want {
t.Fatalf("output:\n%s\n\nwanted:\n%s", output, want)
}
}
const crashSource = `
package main
@ -310,3 +319,22 @@ func main() {
panic("again")
}
`
const goexitExitSource = `
package main
import (
"runtime"
"time"
)
func main() {
go func() {
time.Sleep(time.Millisecond)
}()
i := 0
runtime.SetFinalizer(&i, func(p *int) {})
runtime.GC()
runtime.Goexit()
}
`

View File

@ -1973,7 +1973,9 @@ bgsweep(void)
continue;
}
sweep.parked = true;
g->isbackground = true;
runtime·parkunlock(&gclock, "GC sweep wait");
g->isbackground = false;
}
}
@ -2618,7 +2620,9 @@ runfinq(void)
finq = nil;
if(fb == nil) {
runtime·fingwait = true;
g->isbackground = true;
runtime·parkunlock(&finlock, "finalizer wait");
g->isbackground = false;
continue;
}
runtime·unlock(&finlock);

View File

@ -238,7 +238,9 @@ timerproc(void)
if(delta < 0) {
// No timers left - put goroutine to sleep.
timers.rescheduling = true;
g->isbackground = true;
runtime·parkunlock(&timers, "timer goroutine (idle)");
g->isbackground = false;
continue;
}
// At least one timer pending. Sleep until then.