@@ -119,7 +119,7 @@ func (f *Finder) EachFile(fn func(file *os.File)) {
119119 if err == nil {
120120 fn (file )
121121 } else {
122- f .err = err
122+ f .setError ( err )
123123 }
124124 })
125125}
@@ -166,8 +166,8 @@ func (f *Finder) prepare() {
166166 f .debugf ("PREPARE done. type-flag: %s, concurrency: %d" , f .c .FindFlags , coNum )
167167 f .debugf ("config: %+v" , f .c )
168168 // 创建队列
169- f .ch = make (chan Elem , coNum * 8 )
170- f .dirQueue = make (chan scanDir , coNum * 8 )
169+ f .ch = make (chan Elem , coNum * 8 * 3 )
170+ f .dirQueue = make (chan scanDir , coNum * 8 * 2 )
171171}
172172
173173// Do finding
@@ -190,14 +190,14 @@ func (f *Finder) find() <-chan Elem {
190190
191191 f .prepare ()
192192
193+ // 添加初始任务
194+ f .addRootDirs ()
195+
193196 // 启动工作goroutine
194197 for i := 0 ; i < f .c .Concurrency ; i ++ {
195198 go f .worker (i )
196199 }
197200
198- // 添加初始任务
199- f .addRootDirs ()
200-
201201 // 等待所有任务完成并关闭通道
202202 go func () {
203203 f .debugf ("waiting all task complete ..." )
@@ -217,13 +217,26 @@ func (f *Finder) find() <-chan Elem {
217217
218218// worker 处理目录的工作goroutine
219219func (f * Finder ) worker (index int ) {
220+ f .debugf ("worker#%d STARTING ..." , index )
220221 for sd := range f .dirQueue {
221- func () {
222- defer f .wg .Done ()
223- f .debugf ("worker#%d into dir: %s (depth: %d)" , index , sd .path , sd .depth )
224- f .findDir (sd .path , sd .depth )
225- }()
222+ f .safeFindDir (index , sd .path , sd .depth )
226223 }
224+ f .debugf ("worker#%d DONE." , index )
225+ }
226+
227+ func (f * Finder ) safeFindDir (index int , dirPath string , depth int ) {
228+ f .debugf ("worker#%d into dir: %s (depth: %d)" , index , dirPath , depth )
229+
230+ // recover error and always call wg.Done()
231+ defer func () {
232+ if err := recover (); err != nil {
233+ f .debugf ("worker#%d panic in dir: %s, ERROR: %v" , index , dirPath , err )
234+ f .setError (fmt .Errorf ("worker#%d findDir panic, dir: %s, ERROR: %v" , index , dirPath , err ))
235+ }
236+ f .wg .Done ()
237+ }()
238+
239+ f .findDir (dirPath , depth )
227240}
228241
229242func (f * Finder ) addRootDirs () {
@@ -241,6 +254,7 @@ func (f *Finder) addRootDirs() {
241254
242255 // add task
243256 f .debugf ("add root-dir: %s" , dirPath )
257+ f .wg .Add (1 )
244258 f .dirQueue <- scanDir {path : dirPath }
245259 }
246260}
@@ -308,7 +322,11 @@ func (f *Finder) findDir(dirPath string, depth int) {
308322 // find in sub dir. 添加子目录任务
309323 if cfg .MaxDepth == 0 || depth < cfg .MaxDepth {
310324 f .debugf ("add sub-dir: %s (depth: %d)" , fullPath , depth )
311- f .dirQueue <- scanDir {path : fullPath , depth : depth }
325+ f .wg .Add (1 )
326+ // fix: 创建一个 goroutine 添加子目录任务,不然会造成阻塞
327+ go func (p string , d int ) {
328+ f .dirQueue <- scanDir {path : p , depth : d }
329+ }(fullPath , depth )
312330 }
313331 continue
314332 }
0 commit comments