Merge pull request #1004 from visualfc/goexit2
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 {
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user