osthread: init

This commit is contained in:
Judah Caruso 2025-11-18 18:45:35 -07:00
parent 5a6a8b4fb5
commit 7a36acbf9b

70
osthread/osthread.go Normal file
View file

@ -0,0 +1,70 @@
// Package osthread allows functions to be called on the main operating system thread.
//
// Usage:
//
// func main() {
// osthread.Start(Entrypoint) // Initialize osthread and calls Entrypoint. Blocks until Entrypoint returns.
// }
//
// func Entrypoint() {
// osthread.Call(FuncA) // Call FuncA on the main operating system thread, block until it returns
// // ...
// osthread.Go(FuncB) // Schedule FuncB to be called on the main operating system thread
// // ...
// }
package osthread
import "runtime"
// Start allows arbitrary functions to be run on the main operating system thread.
//
// Start must be called from the program's main function. Once called, it blocks until entrypoint returns.
func Start(entrypoint func()) {
done := make(chan any)
// Run entrypoint in a separate goroutine.
go func() {
defer func() {
done <- nil
}()
entrypoint()
}()
// Call functions in our queue until entrypoint returns.
// These functions are called on the main operating system thread.
for {
select {
case fn := <-queue:
fn()
case <-done:
return
}
}
}
// Go schedules a function to be run on the main operating system thread, returning immediately.
func Go(fn func()) {
queue <- fn
}
// Call schedules a function to be run on the main operating system thread, blocking until it returns.
func Call(fn func()) {
done := make(chan any)
queue <- func() {
defer func() {
done <- nil
}()
fn()
}
<-done
}
var queue chan func()
func init() {
runtime.LockOSThread()
queue = make(chan func(), runtime.GOMAXPROCS(0))
}