aercmsg: add AercFuncMsg and QueueFunc

Introduce AercFuncMsg and QueueFunc. These are used in combination to
queue a function to be run in the main goroutine. This can be used to
prevent data races in delayed function calls (ie from debounce
functions).

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Tim Culverhouse 2022-10-17 15:16:10 -05:00 committed by Robin Jarry
parent 556f346f96
commit 7016c6f86a
2 changed files with 12 additions and 0 deletions

View file

@ -247,6 +247,8 @@ func main() {
switch event := event.(type) { switch event := event.(type) {
case tcell.Event: case tcell.Event:
ui.HandleEvent(event) ui.HandleEvent(event)
case *libui.AercFuncMsg:
event.Func()
case types.WorkerMessage: case types.WorkerMessage:
aerc.HandleMessage(event) aerc.HandleMessage(event)
} }

View file

@ -13,12 +13,22 @@ const (
var MsgChannel = make(chan AercMsg, 50) var MsgChannel = make(chan AercMsg, 50)
type AercFuncMsg struct {
Func func()
}
// QueueRedraw sends a nil message into the MsgChannel. Nothing will handle this // QueueRedraw sends a nil message into the MsgChannel. Nothing will handle this
// message, but a redraw will occur if the UI is marked as invalid // message, but a redraw will occur if the UI is marked as invalid
func QueueRedraw() { func QueueRedraw() {
MsgChannel <- nil MsgChannel <- nil
} }
// QueueFunc queues a function to be called in the main goroutine. This can be
// used to prevent race conditions from delayed functions
func QueueFunc(fn func()) {
MsgChannel <- &AercFuncMsg{Func: fn}
}
// dirty is the dirty state of the UI. Any value other than 0 means the UI is in // dirty is the dirty state of the UI. Any value other than 0 means the UI is in
// a dirty state. Dirty should only be accessed via atomic operations to // a dirty state. Dirty should only be accessed via atomic operations to
// maintain thread safety // maintain thread safety