Skip to content

Commit ac6f1c0

Browse files
author
xiaoyang-chen
committed
feat: only radovskyb-watcher update, merge radovskyb/watcher#123 and radovskyb/watcher#115 for panic interface{} conversion and race condition
1 parent 8485b97 commit ac6f1c0

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

radovskyb-watcher/watcher.go

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,13 @@ func (w *Watcher) listRecursive(name string) (fileList map[string]os.FileInfo, e
348348
func (w *Watcher) Remove(name string) (err error) {
349349

350350
w.mu.Lock()
351-
defer w.mu.Unlock()
351+
err = w.remove(name)
352+
w.mu.Unlock()
353+
return
354+
}
355+
356+
// remove removes either a single file or directory from the file's list but without lock
357+
func (w *Watcher) remove(name string) (err error) {
352358

353359
if name, err = filepath.Abs(name); err != nil {
354360
return
@@ -373,12 +379,17 @@ func (w *Watcher) Remove(name string) (err error) {
373379
return
374380
}
375381

376-
// RemoveRecursive removes either a single file or a directory recursively from
377-
// the file's list.
382+
// RemoveRecursive removes either a single file or a directory recursively from the file's list.
378383
func (w *Watcher) RemoveRecursive(name string) (err error) {
379384

380385
w.mu.Lock()
381-
defer w.mu.Unlock()
386+
err = w.removeRecursive(name)
387+
w.mu.Unlock()
388+
return
389+
}
390+
391+
// removeRecursive removes either a single file or a directory recursively from the file's list but without lock
392+
func (w *Watcher) removeRecursive(name string) (err error) {
382393

383394
if name, err = filepath.Abs(name); err != nil {
384395
return
@@ -394,8 +405,7 @@ func (w *Watcher) RemoveRecursive(name string) (err error) {
394405
if !info.IsDir() {
395406
return
396407
}
397-
// If it's a directory, delete all of it's contents recursively
398-
// from w.files.
408+
// If it's a directory, delete all of it's contents recursively from w.files.
399409
for path := range w.files {
400410
if strings.HasPrefix(path, name) {
401411
delete(w.files, path)
@@ -485,25 +495,23 @@ func (w *Watcher) retrieveFileList() (fileList map[string]os.FileInfo) {
485495
if recursive {
486496
if list, err = w.listRecursive(name); err != nil {
487497
if os.IsNotExist(err) {
488-
w.mu.Unlock()
489-
if name == err.(*os.PathError).Path {
498+
// panic: interface conversion: error is syscall.Errno, not *fs.PathError
499+
if pathError, ok := err.(*os.PathError); ok && pathError.Path == name {
490500
w.Error <- ErrWatchedFileDeleted
491-
w.RemoveRecursive(name)
501+
w.removeRecursive(name)
492502
}
493-
w.mu.Lock()
494503
} else {
495504
w.Error <- err
496505
}
497506
}
498507
} else {
499508
if list, err = w.list(name); err != nil {
500509
if os.IsNotExist(err) {
501-
w.mu.Unlock()
502-
if name == err.(*os.PathError).Path {
510+
// panic: interface conversion: error is syscall.Errno, not *fs.PathError
511+
if pathError, ok := err.(*os.PathError); ok && pathError.Path == name {
503512
w.Error <- ErrWatchedFileDeleted
504-
w.Remove(name)
513+
w.remove(name)
505514
}
506-
w.mu.Lock()
507515
} else {
508516
w.Error <- err
509517
}

0 commit comments

Comments
 (0)