diff options
Diffstat (limited to 'cmd/krino/sort.go')
| -rw-r--r-- | cmd/krino/sort.go | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/cmd/krino/sort.go b/cmd/krino/sort.go index 35d8123..a381239 100644 --- a/cmd/krino/sort.go +++ b/cmd/krino/sort.go @@ -18,6 +18,7 @@ import ( "golang.org/x/term" "git.labunix.xyz/krino/internal/engine" + "git.labunix.xyz/krino/internal/lock" "git.labunix.xyz/krino/internal/plan" "git.labunix.xyz/krino/internal/scan" "git.labunix.xyz/krino/internal/xdg" @@ -126,7 +127,7 @@ func cmdSort(g *globals, names []string, stdout, stderr io.Writer) int { // behind a stuck run. lock.Acquire takes ctx precisely so that wait // is not unbounded in practice: a signal cancels it and Acquire // returns ctx.Err() promptly instead of polling forever. - l, err := sess.Lock(ctx, d, !g.yes) + l, err := lockDir(ctx, sess, d, !g.yes, stderr) if err != nil { if interrupted(err) { // Interrupted while waiting for the lock: an interrupt, not @@ -602,3 +603,17 @@ func interrupted(err error) bool { func stopAfterApply(action rune, err error) bool { return interrupted(err) || action == 'w' } + +// lockDir takes d's lock, saying out loud what a silent wait would hide. +// The lock is tried without waiting first: when it is held and this run may +// wait, the holder is named before the wait begins, so a run that is +// waiting does not look like a run that has hung - there is no timeout on +// the wait, and until it prints something the two are indistinguishable. +func lockDir(ctx context.Context, sess *engine.Session, d *engine.Dir, wait bool, stderr io.Writer) (*lock.Lock, error) { + l, err := sess.Lock(ctx, d, false) + if wait && errors.Is(err, lock.ErrHeld) { + fmt.Fprintf(stderr, "krino: %s: %v; waiting\n", d.Name, err) + return sess.Lock(ctx, d, true) + } + return l, err +} |
