Merge pull request #1004 from visualfc/goexit2

runtime: goexit use thread key
This commit is contained in:
xushiwei
2025-02-17 06:12:28 +08:00
committed by GitHub
3 changed files with 68 additions and 9 deletions

View File

@@ -0,0 +1,57 @@
package main
import (
"runtime"
)
func main() {
demo1()
demo2()
demo3()
}
func demo1() {
ch := make(chan bool)
go func() {
defer func() {
ch <- true
}()
runtime.Goexit()
}()
<-ch
}
func demo2() {
ch := make(chan bool)
go func() {
defer func() {
if r := recover(); r != nil {
panic("must nil")
}
ch <- true
}()
runtime.Goexit()
}()
<-ch
}
func demo3() {
ch := make(chan bool)
go func() {
defer func() {
r := recover()
if r != "error" {
panic("must error")
}
ch <- true
}()
defer func() {
if r := recover(); r != nil {
panic("must nil")
}
panic("error")
}()
runtime.Goexit()
}()
<-ch
}

View File

@@ -0,0 +1 @@
;

View File

@@ -74,21 +74,29 @@ func Rethrow(link *Defer) {
} else {
c.Siglongjmp(link.Addr, 1)
}
} else if link == nil && goexitKey.Get() != nil {
if pthread.Equal(mainThread, pthread.Self()) != 0 {
fatal("no goroutines (main called runtime.Goexit) - deadlock!")
c.Exit(2)
}
pthread.Exit(nil)
}
}
var (
excepKey pthread.Key
goexitKey pthread.Key
mainThread pthread.Thread
goexit struct{}
)
func Goexit() {
panic(goexit)
goexitKey.Set(unsafe.Pointer(&goexitKey))
Rethrow((*Defer)(c.GoDeferData()))
}
func init() {
excepKey.Create(nil)
goexitKey.Create(nil)
mainThread = pthread.Self()
}
@@ -96,13 +104,6 @@ func init() {
// TracePanic prints panic message.
func TracePanic(v any) {
if v == goexit {
if pthread.Equal(mainThread, pthread.Self()) != 0 {
fatal("no goroutines (main called runtime.Goexit) - deadlock!")
c.Exit(2)
}
pthread.Exit(nil)
}
print("panic: ")
printany(v)
println("\n")