Skip to content

Commit d274474

Browse files
committed
Band-aid fix for rare crashes when refreshing files
Users have filed issues with crash reports that seem to indicate that the FileTreeViewModel gets swapped out (by a refresh) while a call to itemsSelected is in progress, iterating over the previous items. Guard against this by locking the mutex that we already have for this for the duration of the call. I don't have a good way of testing whether the fix helps, because the crashes only occurred very infrequently. Let's just see if the crash reports stop coming in after we ship this. Note also that this is only the minimal fix for the crashes that were reported. Theoretically, the same problem could happen for a key handler itself, but we never saw reports about that, so we don't bother doing anything about that yet. Note also that long-term I envision a different solution to this class of problems (discussed in #2974), that's why I want to avoid locking mutexes more than necessary now.
1 parent d1d2bb2 commit d274474

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

pkg/gui/controllers/files_controller.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
4444
{
4545
Key: opts.GetKey(opts.Config.Universal.Select),
4646
Handler: self.withItems(self.press),
47-
GetDisabledReason: self.require(self.itemsSelected()),
47+
GetDisabledReason: self.require(self.withFileTreeViewModelMutex(self.itemsSelected())),
4848
Description: self.c.Tr.Stage,
4949
Tooltip: self.c.Tr.StageTooltip,
5050
DisplayOnScreen: true,
@@ -91,7 +91,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
9191
{
9292
Key: opts.GetKey(opts.Config.Universal.Edit),
9393
Handler: self.withItems(self.edit),
94-
GetDisabledReason: self.require(self.itemsSelected(self.canEditFiles)),
94+
GetDisabledReason: self.require(self.withFileTreeViewModelMutex(self.itemsSelected(self.canEditFiles))),
9595
Description: self.c.Tr.Edit,
9696
Tooltip: self.c.Tr.EditFileTooltip,
9797
DisplayOnScreen: true,
@@ -145,7 +145,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
145145
{
146146
Key: opts.GetKey(opts.Config.Universal.Remove),
147147
Handler: self.withItems(self.remove),
148-
GetDisabledReason: self.require(self.itemsSelected(self.canRemove)),
148+
GetDisabledReason: self.withFileTreeViewModelMutex(self.require(self.itemsSelected(self.canRemove))),
149149
Description: self.c.Tr.Discard,
150150
Tooltip: self.c.Tr.DiscardFileChangesTooltip,
151151
OpensMenu: true,
@@ -182,7 +182,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
182182
Handler: self.withItems(self.openMergeConflictMenu),
183183
Description: self.c.Tr.ViewMergeConflictOptions,
184184
Tooltip: self.c.Tr.ViewMergeConflictOptionsTooltip,
185-
GetDisabledReason: self.require(self.itemsSelected(self.canOpenMergeConflictMenu)),
185+
GetDisabledReason: self.require(self.withFileTreeViewModelMutex(self.itemsSelected(self.canOpenMergeConflictMenu))),
186186
OpensMenu: true,
187187
DisplayOnScreen: true,
188188
},
@@ -209,6 +209,15 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
209209
}
210210
}
211211

212+
func (self *FilesController) withFileTreeViewModelMutex(callback func() *types.DisabledReason) func() *types.DisabledReason {
213+
return func() *types.DisabledReason {
214+
self.c.Contexts().Files.FileTreeViewModel.RWMutex.RLock()
215+
defer self.c.Contexts().Files.FileTreeViewModel.RWMutex.RUnlock()
216+
217+
return callback()
218+
}
219+
}
220+
212221
func (self *FilesController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
213222
return []*gocui.ViewMouseBinding{
214223
{

0 commit comments

Comments
 (0)