From 5d25b3fb9a567d65f76df3ce3ed58d84edf948a7 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Mon, 24 Nov 2025 19:43:25 -0500 Subject: [PATCH] Main-locked threads are panic wrapped --- phases.go | 32 ++++++++++++++++++++------------ util.go | 32 +++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/phases.go b/phases.go index e4ffbe0..2091fe7 100644 --- a/phases.go +++ b/phases.go @@ -234,9 +234,9 @@ func (this *environment) phase70Running() bool { } } - result := make(chan bool) + bodyReturn := make(chan bool) go func() { - result <- this.phase70RunningBody() + bodyReturn <- this.phase70RunningBody() if this.main != nil { shutdownCtx, done := context.WithTimeout( context.Background(), @@ -247,19 +247,12 @@ func (this *environment) phase70Running() bool { } }() + mainReturn := false if this.main != nil { - mainActor := this.main.(Actor) - if this.Verb() { log.Printf("(i) (70) binding %s to main thread", mainActor.Type()) } - runtime.LockOSThread() - defer runtime.UnlockOSThread() - err := this.main.RunMain() - if err != nil { - log.Printf("XXX [%s] main thread failed: %v", mainActor.Type(), err) - } - if this.Verb() { log.Printf("(i) (70) main thread exited") } + mainReturn = this.phase70_2MainBind() } - return <- result + return <- bodyReturn && mainReturn } func (this *environment) phase70RunningBody() bool { @@ -294,6 +287,21 @@ func (this *environment) phase70RunningBody() bool { return true } +func (this *environment) phase70_2MainBind() bool{ + mainActor := this.main.(Actor) + if this.Verb() { log.Printf("... (70.2) binding %s to main thread", mainActor.Type()) } + runtime.LockOSThread() + if this.Verb() { log.Printf(".// (70.2) main thread bind complete") } + defer runtime.UnlockOSThread() + err := panicWrap(this.main.RunMain) + if err != nil { + log.Printf("XXX [%s] main thread failed: %v", mainActor.Type(), err) + return false + } + if this.Verb() { log.Printf("(i) (70.2) main thread exited") } + return true +} + func (this *environment) phase70_5Trimming() bool { if this.Verb() { log.Println("... (70.5) trimming") } var trimmable []Trimmable diff --git a/util.go b/util.go index f931fc7..a853a54 100644 --- a/util.go +++ b/util.go @@ -14,16 +14,34 @@ import "sync/atomic" import "unicode/utf8" import "runtime/debug" -func panicErr(message any, stack []byte) (err error) { - if panErr, ok := message.(error); ok { - err = panErr +type panicError struct { + wrapped error + stack []byte +} + +func (this panicError) Error() string { + if this.stack == nil { + return this.wrapped.Error() } else { - err = errors.New(fmt.Sprint(message)) + return fmt.Sprintf("%v: %s", this.wrapped, this.stack) } - if stack != nil { - err = fmt.Errorf("%w: %s", err, stack) +} + +func (this panicError) Unwrap() error { + return this.wrapped +} + +func panicErr(message any, stack []byte) (err error) { + var wrapped error + if panErr, ok := message.(error); ok { + wrapped = panErr + } else { + wrapped = errors.New(fmt.Sprint(message)) + } + return panicError { + wrapped: wrapped, + stack: stack, } - return err } func defaul[T comparable](value, def T) T {