zworld/engine/renderapi/command/thread_worker.go

71 lines
1.3 KiB
Go
Raw Normal View History

2024-01-14 22:56:06 +08:00
package command
import (
"runtime"
)
type ThreadWorker struct {
name string
buffer int
work chan func()
}
func NewThreadWorker(name string, buffer int, locked bool) *ThreadWorker {
w := &ThreadWorker{
name: name,
buffer: buffer,
work: make(chan func(), buffer),
}
go w.workloop(locked)
return w
}
func (tw *ThreadWorker) workloop(locked bool) {
// lock the worker to its current thread
if locked {
runtime.LockOSThread()
}
// work loop
for {
work, more := <-tw.work
if !more {
break
}
work()
}
}
// Invoke schedules a callback to be called from the worker thread
func (tw *ThreadWorker) Invoke(callback func()) {
tw.work <- callback
}
// InvokeSync schedules a callback to be called on the worker thread,
// and blocks until the callback is finished.
func (tw *ThreadWorker) InvokeSync(callback func()) {
done := make(chan struct{})
tw.work <- func() {
callback()
done <- struct{}{}
}
<-done
}
// Aborts the worker, cancelling any pending work.
func (tw *ThreadWorker) Abort() {
close(tw.work)
}
// Stop the worker and release any resources. Blocks until all work in completed.
func (tw *ThreadWorker) Stop() {
tw.InvokeSync(func() {
close(tw.work)
})
}
// Flush blocks the caller until all pending work is completed
func (tw *ThreadWorker) Flush() {
tw.InvokeSync(func() {})
}