github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/rtutils/singlethread/singlethread.go (about) 1 package singlethread 2 3 import ( 4 "fmt" 5 "sync" 6 ) 7 8 type callback struct { 9 funcToCall func() error 10 funcResult chan (error) 11 } 12 13 type Thread struct { 14 callback chan (callback) 15 closed bool 16 mutex *sync.Mutex 17 } 18 19 func New() *Thread { 20 t := &Thread{ 21 make(chan (callback)), 22 false, 23 &sync.Mutex{}, 24 } 25 go t.run() 26 return t 27 } 28 29 func (t *Thread) run() { 30 for { 31 callback, gotCallback := <-t.callback 32 if gotCallback { 33 callback.funcResult <- callback.funcToCall() 34 } else { 35 return 36 } 37 } 38 } 39 40 func (t *Thread) Run(funcToCall func() error) error { 41 t.mutex.Lock() 42 defer t.mutex.Unlock() 43 44 if t.closed { 45 return fmt.Errorf("thread is closed") 46 } 47 48 callback := callback{funcToCall, make(chan (error))} 49 t.callback <- callback 50 return <-callback.funcResult 51 } 52 53 func (t *Thread) Close() { 54 t.mutex.Lock() 55 defer t.mutex.Unlock() 56 57 close(t.callback) 58 t.closed = true 59 }