mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-25 12:24:47 +02:00
prevent deadlocks.
Hard to choose between the lock with a defer unlock in an anonymous function vs just having an explicit unlock at the end with additional unlocks before any early returns. The former is less error prone, but the former is much more readable, especially if the anonymous function would have needed to return an error value.
This commit is contained in:
parent
94d26d00ba
commit
f4e552f982
@ -395,9 +395,6 @@ func (gui *Gui) replaceContext(c Context) error {
|
|||||||
|
|
||||||
func (gui *Gui) pushContext(c Context) error {
|
func (gui *Gui) pushContext(c Context) error {
|
||||||
gui.g.Update(func(*gocui.Gui) error {
|
gui.g.Update(func(*gocui.Gui) error {
|
||||||
gui.State.ContextManager.Lock()
|
|
||||||
defer gui.State.ContextManager.Unlock()
|
|
||||||
|
|
||||||
return gui.pushContextDirect(c)
|
return gui.pushContextDirect(c)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -405,12 +402,15 @@ func (gui *Gui) pushContext(c Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) pushContextDirect(c Context) error {
|
func (gui *Gui) pushContextDirect(c Context) error {
|
||||||
|
gui.State.ContextManager.Lock()
|
||||||
|
|
||||||
// push onto stack
|
// push onto stack
|
||||||
// if we are switching to a side context, remove all other contexts in the stack
|
// if we are switching to a side context, remove all other contexts in the stack
|
||||||
if c.GetKind() == SIDE_CONTEXT {
|
if c.GetKind() == SIDE_CONTEXT {
|
||||||
for _, stackContext := range gui.State.ContextManager.ContextStack {
|
for _, stackContext := range gui.State.ContextManager.ContextStack {
|
||||||
if stackContext.GetKey() != c.GetKey() {
|
if stackContext.GetKey() != c.GetKey() {
|
||||||
if err := gui.deactivateContext(stackContext); err != nil {
|
if err := gui.deactivateContext(stackContext); err != nil {
|
||||||
|
gui.State.ContextManager.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -424,6 +424,8 @@ func (gui *Gui) pushContextDirect(c Context) error {
|
|||||||
gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c)
|
gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gui.State.ContextManager.Unlock()
|
||||||
|
|
||||||
return gui.activateContext(c)
|
return gui.activateContext(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,10 +441,10 @@ func (gui *Gui) pushContextWithView(viewName string) error {
|
|||||||
func (gui *Gui) returnFromContext() error {
|
func (gui *Gui) returnFromContext() error {
|
||||||
gui.g.Update(func(*gocui.Gui) error {
|
gui.g.Update(func(*gocui.Gui) error {
|
||||||
gui.State.ContextManager.Lock()
|
gui.State.ContextManager.Lock()
|
||||||
defer gui.State.ContextManager.Unlock()
|
|
||||||
|
|
||||||
if len(gui.State.ContextManager.ContextStack) == 1 {
|
if len(gui.State.ContextManager.ContextStack) == 1 {
|
||||||
// cannot escape from bottommost context
|
// cannot escape from bottommost context
|
||||||
|
gui.State.ContextManager.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,6 +455,8 @@ func (gui *Gui) returnFromContext() error {
|
|||||||
|
|
||||||
gui.State.ContextManager.ContextStack = gui.State.ContextManager.ContextStack[:n]
|
gui.State.ContextManager.ContextStack = gui.State.ContextManager.ContextStack[:n]
|
||||||
|
|
||||||
|
gui.State.ContextManager.Unlock()
|
||||||
|
|
||||||
if err := gui.deactivateContext(currentContext); err != nil {
|
if err := gui.deactivateContext(currentContext); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -513,10 +517,8 @@ func (gui *Gui) postRefreshUpdate(c Context) error {
|
|||||||
func (gui *Gui) activateContext(c Context) error {
|
func (gui *Gui) activateContext(c Context) error {
|
||||||
viewName := c.GetViewName()
|
viewName := c.GetViewName()
|
||||||
v, err := gui.g.View(viewName)
|
v, err := gui.g.View(viewName)
|
||||||
// if view no longer exists, pop again
|
|
||||||
// (note: this should never happen, unless we call this code before our views are initialised)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.returnFromContext()
|
return err
|
||||||
}
|
}
|
||||||
originalViewContextKey := ContextKey(v.Context)
|
originalViewContextKey := ContextKey(v.Context)
|
||||||
|
|
||||||
@ -532,8 +534,7 @@ func (gui *Gui) activateContext(c Context) error {
|
|||||||
gui.setViewTabForContext(c)
|
gui.setViewTabForContext(c)
|
||||||
|
|
||||||
if _, err := gui.g.SetCurrentView(viewName); err != nil {
|
if _, err := gui.g.SetCurrentView(viewName); err != nil {
|
||||||
// if view no longer exists, pop again
|
return err
|
||||||
return gui.returnFromContext()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v.Visible = true
|
v.Visible = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user