From 03bdbb064fe8fd2be743136f6b1fed281df5c113 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Mon, 2 Mar 2015 19:44:16 +0100 Subject: [PATCH] Allow cancelling walker --- pipe/pipe.go | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/pipe/pipe.go b/pipe/pipe.go index 257e41d1e..c3534b7bf 100644 --- a/pipe/pipe.go +++ b/pipe/pipe.go @@ -1,6 +1,7 @@ package pipe import ( + "errors" "fmt" "os" "path/filepath" @@ -50,6 +51,8 @@ func isFile(fi os.FileInfo) bool { return fi.Mode()&(os.ModeType|os.ModeCharDevice) == 0 } +var errCancelled = errors.New("walk cancelled") + func walk(path string, done chan struct{}, jobs chan<- interface{}, res chan<- interface{}) error { info, err := os.Lstat(path) if err != nil { @@ -57,7 +60,11 @@ func walk(path string, done chan struct{}, jobs chan<- interface{}, res chan<- i } if !info.IsDir() { - jobs <- Entry{Info: info, Path: path, Result: res} + select { + case jobs <- Entry{Info: info, Path: path, Result: res}: + case <-done: + return errCancelled + } return nil } @@ -76,8 +83,12 @@ func walk(path string, done chan struct{}, jobs chan<- interface{}, res chan<- i fi, err := os.Lstat(subpath) if err != nil { - // entCh <- Entry{Info: fi, Error: err, Result: ch} - return err + select { + case jobs <- Entry{Info: fi, Error: err, Result: ch}: + case <-done: + return errCancelled + } + continue } if isDir(fi) { @@ -87,11 +98,19 @@ func walk(path string, done chan struct{}, jobs chan<- interface{}, res chan<- i } } else { - jobs <- Entry{Info: fi, Path: subpath, Result: ch} + select { + case jobs <- Entry{Info: fi, Path: subpath, Result: ch}: + case <-done: + return errCancelled + } } } - jobs <- Dir{Path: path, Info: info, Entries: entries, Result: res} + select { + case jobs <- Dir{Path: path, Info: info, Entries: entries, Result: res}: + case <-done: + return errCancelled + } return nil }