diff options
Diffstat (limited to 'gui/internal/model/plan.go')
| -rw-r--r-- | gui/internal/model/plan.go | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/gui/internal/model/plan.go b/gui/internal/model/plan.go index 31a783b..31c12dd 100644 --- a/gui/internal/model/plan.go +++ b/gui/internal/model/plan.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "sort" + "sync/atomic" "time" "git.labunix.xyz/krino/internal/engine" @@ -53,14 +54,16 @@ type PlanTab struct { dp *engine.DirPlan lock *lock.Lock - // applying is set while Apply is in flight. Close must refuse then: + // applying is set while Apply is in flight, and read from the main loop + // while the apply runs on a worker, so it is atomic. Close must refuse + // while it is set: // releasing the lock and closing the log under a running apply moves // files the log never records, so undo cannot see them, and unlocks a // directory krino is still working in. The window can reach Close from // several places while an apply runs - saving rules or settings, adding // a directory, closing the window - so the refusal lives here rather // than in whichever of them remembers. - applying bool + applying atomic.Bool // testBeforeApply, when set, is called just before the engine's Apply // begins, so a test can act while the apply is in flight. @@ -113,7 +116,7 @@ func (t *PlanTab) Run() string { return t.sess.Run() } // Close releases the directory's lock and ends the run, which Apply also // does once the plan is history. Closing twice is not an error. func (t *PlanTab) Close() error { - if t.applying { + if t.applying.Load() { return ErrApplying } if t.lock == nil { @@ -341,12 +344,12 @@ func (t *PlanTab) Apply(ctx context.Context) (*engine.ApplyResult, error) { approved[r.Rel] = true } } - t.applying = true + t.applying.Store(true) if t.testBeforeApply != nil { t.testBeforeApply() } res, err := t.sess.Apply(ctx, t.dp, approved) - t.applying = false + t.applying.Store(false) t.Applied = true // An applied plan is history: the run is over and the directory free // again, without closing the window (GUI design ยง3). |
