From 2ac0e9e086dad67014b6b0b5b2a695b138a02842 Mon Sep 17 00:00:00 2001 From: Konstantin Vorobyev Date: Wed, 20 Jun 2018 16:54:24 +0200 Subject: [PATCH 1/2] Block main event loop with mutex during Suspend() call --- application.go | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/application.go b/application.go index 31821d9..2df2b74 100644 --- a/application.go +++ b/application.go @@ -41,8 +41,8 @@ type Application struct { // was drawn. afterDraw func(screen tcell.Screen) - // If this value is true, the application has entered suspended mode. - suspended bool + // Used for events loop lock during Suspend() + suspendMutex sync.Mutex } // NewApplication creates and returns a new application. @@ -103,28 +103,20 @@ func (a *Application) Run() error { // Start event loop. for { + // Do not poll events during suspend mode + a.suspendMutex.Lock() a.Lock() screen := a.screen - if a.suspended { - a.suspended = false // Clear previous suspended flag. - } a.Unlock() if screen == nil { + a.suspendMutex.Unlock() break } // Wait for next event. event := a.screen.PollEvent() + a.suspendMutex.Unlock() if event == nil { - a.Lock() - if a.suspended { - // This screen was renewed due to suspended mode. - a.suspended = false - a.Unlock() - continue // Resume. - } - a.Unlock() - // The screen was finalized. Exit the loop. break } @@ -190,14 +182,14 @@ func (a *Application) Stop() { func (a *Application) Suspend(f func()) bool { a.Lock() - if a.suspended || a.screen == nil { + if a.screen == nil { // Application is already suspended. a.Unlock() return false } // Enter suspended mode. - a.suspended = true + a.suspendMutex.Lock() a.Unlock() a.Stop() @@ -217,10 +209,12 @@ func (a *Application) Suspend(f func()) bool { var err error a.screen, err = tcell.NewScreen() if err != nil { + a.suspendMutex.Unlock() a.Unlock() panic(err) } if err = a.screen.Init(); err != nil { + a.suspendMutex.Unlock() a.Unlock() panic(err) } @@ -228,6 +222,7 @@ func (a *Application) Suspend(f func()) bool { a.Draw() // Continue application loop. + a.suspendMutex.Unlock() return true } From 01a39a486dcc438baa4fb091ab301a20898a02b1 Mon Sep 17 00:00:00 2001 From: Konstantin Vorobyev Date: Wed, 20 Jun 2018 19:32:19 +0200 Subject: [PATCH 2/2] Review feedback --- application.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/application.go b/application.go index 2df2b74..d3b5f23 100644 --- a/application.go +++ b/application.go @@ -41,7 +41,7 @@ type Application struct { // was drawn. afterDraw func(screen tcell.Screen) - // Used for events loop lock during Suspend() + // Halts the event loop during suspended mode suspendMutex sync.Mutex } @@ -183,13 +183,14 @@ func (a *Application) Suspend(f func()) bool { a.Lock() if a.screen == nil { - // Application is already suspended. + // Screen has not yet been initialized a.Unlock() return false } // Enter suspended mode. a.suspendMutex.Lock() + defer a.suspendMutex.Unlock() a.Unlock() a.Stop() @@ -209,12 +210,10 @@ func (a *Application) Suspend(f func()) bool { var err error a.screen, err = tcell.NewScreen() if err != nil { - a.suspendMutex.Unlock() a.Unlock() panic(err) } if err = a.screen.Init(); err != nil { - a.suspendMutex.Unlock() a.Unlock() panic(err) } @@ -222,7 +221,6 @@ func (a *Application) Suspend(f func()) bool { a.Draw() // Continue application loop. - a.suspendMutex.Unlock() return true }