diff options
| author | Russ Cox <rsc@golang.org> | 2013-07-26 13:54:44 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2013-07-26 13:54:44 -0400 |
| commit | 14062efb16e3c69adaf655d0b545189036929368 (patch) | |
| tree | 844645ceabf0f945a109a1c4992a0866745984ff /src/pkg/runtime/proc.c | |
| parent | f8a850b250655bd26f5da4cfe7299b4a32be28fa (diff) | |
| download | go-14062efb16e3c69adaf655d0b545189036929368.tar.xz | |
runtime: handle runtime.Goexit during init
Fixes #5963.
R=golang-dev, dsymonds, dvyukov
CC=golang-dev
https://golang.org/cl/11879045
Diffstat (limited to 'src/pkg/runtime/proc.c')
| -rw-r--r-- | src/pkg/runtime/proc.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index 135a112f52..6e3c274560 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -160,10 +160,14 @@ extern void main·main(void); static FuncVal scavenger = {runtime·MHeap_Scavenger}; +static FuncVal initDone = { runtime·unlockOSThread }; + // The main goroutine. void runtime·main(void) { + Defer d; + newm(sysmon, nil); // Lock the main goroutine onto this, the main OS thread, @@ -173,10 +177,24 @@ runtime·main(void) // by calling runtime.LockOSThread during initialization // to preserve the lock. runtime·lockOSThread(); + + // Defer unlock so that runtime.Goexit during init does the unlock too. + d.fn = &initDone; + d.siz = 0; + d.link = g->defer; + d.argp = (void*)-1; + d.special = true; + d.free = false; + g->defer = &d; + if(m != &runtime·m0) runtime·throw("runtime·main not on m0"); runtime·newproc1(&scavenger, nil, 0, 0, runtime·main); main·init(); + + if(g->defer != &d || d.fn != &initDone) + runtime·throw("runtime: bad defer entry after init"); + g->defer = d.link; runtime·unlockOSThread(); main·main(); |
