runtime: goexit use thread key
This commit is contained in:
57
compiler/cl/_testgo/goexit/in.go
Normal file
57
compiler/cl/_testgo/goexit/in.go
Normal 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
|
||||||
|
}
|
||||||
1
compiler/cl/_testgo/goexit/out.ll
Normal file
1
compiler/cl/_testgo/goexit/out.ll
Normal file
@@ -0,0 +1 @@
|
|||||||
|
;
|
||||||
@@ -74,21 +74,29 @@ func Rethrow(link *Defer) {
|
|||||||
} else {
|
} else {
|
||||||
c.Siglongjmp(link.Addr, 1)
|
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 (
|
var (
|
||||||
excepKey pthread.Key
|
excepKey pthread.Key
|
||||||
|
goexitKey pthread.Key
|
||||||
mainThread pthread.Thread
|
mainThread pthread.Thread
|
||||||
goexit struct{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Goexit() {
|
func Goexit() {
|
||||||
panic(goexit)
|
goexitKey.Set(unsafe.Pointer(&goexitKey))
|
||||||
|
Rethrow((*Defer)(c.GoDeferData()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
excepKey.Create(nil)
|
excepKey.Create(nil)
|
||||||
|
goexitKey.Create(nil)
|
||||||
mainThread = pthread.Self()
|
mainThread = pthread.Self()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,13 +104,6 @@ func init() {
|
|||||||
|
|
||||||
// TracePanic prints panic message.
|
// TracePanic prints panic message.
|
||||||
func TracePanic(v any) {
|
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: ")
|
print("panic: ")
|
||||||
printany(v)
|
printany(v)
|
||||||
println("\n")
|
println("\n")
|
||||||
|
|||||||
Reference in New Issue
Block a user