mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Assert that Model() and Context() are only accessed on the UI thread
The bounce model requires that a worker never touch UI-thread-owned state: it should capture what it needs on the UI thread and pass that in. Guard the two central accessors -- Model() (the git model) and Context() (the context manager, which owns the mutable current-context/stack) -- with a debug-only panic when they're called off the UI thread. Since the integration tests run with -debug, a stray worker access now fails deterministically and points at itself, rather than surfacing later as a probabilistic data race. One supporting change make the assertion usable: the integration test driver inspects gui state from the test goroutine, so GuiDriver.CurrentContext reads the context manager directly rather than through the now-guarded c.Context(). Contexts() (the registry of context objects) is deliberately left unguarded: workers legitimately fetch a context to grab its mutex or check identity, so a blanket assertion there would flag safe accesses. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c23bcd6d94
commit
e299de3270
|
|
@ -58,7 +58,18 @@ func (self *guiCommon) PauseBackgroundRefreshes(pause bool) {
|
|||
self.gui.BackgroundRoutineMgr.PauseBackgroundRefreshes(pause)
|
||||
}
|
||||
|
||||
// assertOnUIThread panics (in debug builds) if called from a worker goroutine.
|
||||
// Use it to guard accessors for state that only the UI thread may touch, so
|
||||
// that a stray worker access fails deterministically -- and points at itself --
|
||||
// rather than surfacing later as a probabilistic data race.
|
||||
func (self *guiCommon) assertOnUIThread(accessor string) {
|
||||
if self.GetConfig().GetDebug() && !self.GocuiGui().IsUIThread() {
|
||||
panic(accessor + " accessed from a worker")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *guiCommon) Context() types.IContextMgr {
|
||||
self.assertOnUIThread("Context()")
|
||||
return self.gui.State.ContextMgr
|
||||
}
|
||||
|
||||
|
|
@ -113,6 +124,7 @@ func (self *guiCommon) Modes() *types.Modes {
|
|||
}
|
||||
|
||||
func (self *guiCommon) Model() *types.Model {
|
||||
self.assertOnUIThread("Model()")
|
||||
return self.gui.State.Model
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,10 @@ func (self *GuiDriver) Keys() config.KeybindingConfig {
|
|||
}
|
||||
|
||||
func (self *GuiDriver) CurrentContext() types.Context {
|
||||
return self.gui.c.Context().Current()
|
||||
// Read the context manager directly rather than through c.Context(): the
|
||||
// driver runs on the test goroutine, not the UI thread, so it must bypass
|
||||
// the UI-thread assertion that accessor carries.
|
||||
return self.gui.State.ContextMgr.Current()
|
||||
}
|
||||
|
||||
func (self *GuiDriver) ContextForView(viewName string) types.Context {
|
||||
|
|
|
|||
Loading…
Reference in a new issue