Skip to content

Commit

Permalink
FSEvents: fix bug where rewatching path fails across channels
Browse files Browse the repository at this point in the history
The following code reproduces a bug where if you watch a parent
and child directory across multiple channels and then call
notify.Stop() on the either channel, any subsequent calls to
notify.Watch() on a grandparent directory will fail:

```go
package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/rjeczalik/notify"
)

func watch(path string) chan notify.EventInfo {
	c := make(chan notify.EventInfo, 1)
	if err := notify.Watch(path+"...", c, notify.All); err != nil {
		panic(err)
	}
	return c
}

func main() {
	os.MkdirAll("./a/b/c", 0775)
	defer os.RemoveAll("./a")

	// watch a child and parent path across multiple channels.
	// this can happen in any order.
	ch1 := watch("./a/b/c")
	ch2 := watch("./a/b")

	// unwatch ./a/b -- this is what causes the panic on the next line.
	// note that this also fails if we notify.Stop(ch1) instead.
	notify.Stop(ch2)

	// watching ./a will now return errNotWatched.
	ch3 := watch("./a")

	// just a test to make sure watching still works when we get here.
	go func() { ioutil.WriteFile("a/b/c/d", []byte("X"), 0664) }()
	fmt.Println(<-ch1, <-ch3)
}
```

Fortunately we can fix this failure by simply not returning
errNotWatched from unwatch(), which simply performs a no-op
if there is no active stream for the path when Unwatch() is
called.
  • Loading branch information
lsegal committed Jun 22, 2018
1 parent d152f3c commit ea65ea2
Showing 1 changed file with 2 additions and 3 deletions.
5 changes: 2 additions & 3 deletions watcher_fsevents.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,9 @@ func (fse *fsevents) watch(path string, event Event, isrec int32) (err error) {

func (fse *fsevents) unwatch(path string) (err error) {
w, ok := fse.watches[path]
if !ok {
return errNotWatched
if ok {
w.stream.Stop()
}
w.stream.Stop()
delete(fse.watches, path)
return nil
}
Expand Down

0 comments on commit ea65ea2

Please sign in to comment.