mirror of https://github.com/rivo/tview
Add deadlock guard for Queue{Update,Event}
This commit adds an atomic bool into Application that ensures that the user can never call QueueUpdate or QueueEvent in the main loop. Previously, when the user does this, the application would deadlock and freeze forever. The user would often have to kill the process manually to get out of this state. Now, the application will panic, indicating the bug immediately.pull/985/head
parent
ed116790de
commit
986849f093
@ -0,0 +1,48 @@
|
||||
package tview
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
)
|
||||
|
||||
func TestApplication_deadlock_check(t *testing.T) {
|
||||
screen := tcell.NewSimulationScreen("UTF-8")
|
||||
if err := screen.Init(); err != nil {
|
||||
t.Errorf("screen.Init() error = %v, want nil", err)
|
||||
}
|
||||
|
||||
app := NewApplication()
|
||||
app.SetScreen(screen)
|
||||
app.SetRoot(NewBox().SetTitle("Hello, world!"), true)
|
||||
|
||||
panicCh := make(chan bool)
|
||||
go func() {
|
||||
defer func() {
|
||||
panicCh <- recover() != nil
|
||||
}()
|
||||
if err := app.Run(); err != nil {
|
||||
t.Errorf("Application.Run() error = %v, want nil", err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
app.QueueUpdate(func() {
|
||||
app.QueueUpdate(func() {
|
||||
t.Errorf("impossible case")
|
||||
})
|
||||
})
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("deadlock detected")
|
||||
case panicked := <-panicCh:
|
||||
if panicked {
|
||||
t.Log("panic detected, deadlock avoided")
|
||||
} else {
|
||||
t.Log("impossible case where deadlock did not occur, but things are working fine :)")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue