// List the path into out // // Ignores everything which isn't Storable, eg links etc func (f *Fs) List(out fs.ListOpts, dir string) { defer out.Finished() dir = filterFragment(f.cleanUtf8(dir)) root := filepath.Join(f.root, dir) _, err := os.Stat(root) if err != nil { out.SetError(fs.ErrorDirNotFound) return } in := make(chan listArgs, out.Buffer()) var wg sync.WaitGroup // sync closing of go routines var traversing sync.WaitGroup // running directory traversals // Start the process traversing.Add(1) in <- listArgs{remote: dir, dirpath: root, level: out.Level() - 1} for i := 0; i < fs.Config.Checkers; i++ { wg.Add(1) go func() { defer wg.Done() for job := range in { if out.IsFinished() { continue } newJobs := f.list(out, job.remote, job.dirpath, job.level) // Now we have traversed this directory, send // these ones off for traversal if len(newJobs) != 0 { traversing.Add(len(newJobs)) go func() { for _, newJob := range newJobs { in <- newJob } }() } traversing.Done() } }() } // Wait for traversal to finish traversing.Wait() close(in) wg.Wait() }