aboutsummaryrefslogtreecommitdiff
path: root/cmd/krino/sort.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/krino/sort.go')
-rw-r--r--cmd/krino/sort.go17
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
+}