]> go.fuhry.dev Git - fsnotify.git/commitdiff
Close inotify fd from watcher, not from poller
authorPieter Droogendijk <pieter@binky.org.uk>
Sat, 7 Feb 2015 21:39:58 +0000 (22:39 +0100)
committerNathan Youngman <git@nathany.com>
Sun, 8 Feb 2015 20:22:31 +0000 (13:22 -0700)
inotify.go
inotify_poller.go
inotify_test.go

index e02bf12b8bf1f2dfdeffdb584c3e6ae454c30941..5aa185b88dfeebdc87891b8982f40ddb4a7abf29 100644 (file)
@@ -23,6 +23,7 @@ type Watcher struct {
        Events   chan Event
        Errors   chan error
        mu       sync.Mutex // Map access
+       fd       int
        poller   *fdPoller
        watches  map[string]*watch // Map of inotify watches (key: path)
        paths    map[int]string    // Map of watched paths (key: watch descriptor)
@@ -40,9 +41,11 @@ func NewWatcher() (*Watcher, error) {
        // Create epoll
        poller, err := newFdPoller(fd)
        if err != nil {
+               syscall.Close(fd)
                return nil, err
        }
        w := &Watcher{
+               fd:       fd,
                poller:   poller,
                watches:  make(map[string]*watch),
                paths:    make(map[int]string),
@@ -103,7 +106,7 @@ func (w *Watcher) Add(name string) error {
                watchEntry.flags |= flags
                flags |= syscall.IN_MASK_ADD
        }
-       wd, errno := syscall.InotifyAddWatch(w.poller.fd, name, flags)
+       wd, errno := syscall.InotifyAddWatch(w.fd, name, flags)
        if wd == -1 {
                return errno
        }
@@ -129,7 +132,7 @@ func (w *Watcher) Remove(name string) error {
        if !ok {
                return fmt.Errorf("can't remove non-existent inotify watch for: %s", name)
        }
-       success, errno := syscall.InotifyRmWatch(w.poller.fd, watch.wd)
+       success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
        if success == -1 {
                return errno
        }
@@ -155,6 +158,7 @@ func (w *Watcher) readEvents() {
        defer close(w.doneresp)
        defer close(w.Errors)
        defer close(w.Events)
+       defer syscall.Close(w.fd)
        defer w.poller.close()
 
        for {
@@ -177,7 +181,7 @@ func (w *Watcher) readEvents() {
                        continue
                }
 
-               n, errno = syscall.Read(w.poller.fd, buf[:])
+               n, errno = syscall.Read(w.fd, buf[:])
                // If a signal interrupted execution, see if we've been asked to close, and try again.
                // http://man7.org/linux/man-pages/man7/signal.7.html :
                // "Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable"
index 8a95df61c8bec3122009c0cbbd5829d31dab07fe..2f9cb23234c35656b2b38aa67367243b5d0aabed 100644 (file)
@@ -33,7 +33,6 @@ func newFdPoller(fd int) (*fdPoller, error) {
        // Create pipe; pipe[0] is the read end, pipe[1] the write end.
        errno = syscall.Pipe(poller.pipe[:])
        if errno != nil {
-               syscall.Close(poller.fd)
                syscall.Close(poller.epfd)
                return nil, errno
        }
@@ -45,7 +44,6 @@ func newFdPoller(fd int) (*fdPoller, error) {
        }
        errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event)
        if errno != nil {
-               syscall.Close(poller.fd)
                syscall.Close(poller.epfd)
                syscall.Close(poller.pipe[0])
                syscall.Close(poller.pipe[1])
@@ -59,7 +57,6 @@ func newFdPoller(fd int) (*fdPoller, error) {
        }
        errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event)
        if errno != nil {
-               syscall.Close(poller.fd)
                syscall.Close(poller.epfd)
                syscall.Close(poller.pipe[0])
                syscall.Close(poller.pipe[1])
@@ -171,10 +168,9 @@ func (poller *fdPoller) clearWake() error {
        return nil
 }
 
-// Close all file descriptors.
+// Close all poller file descriptors, but not the one passed to it.
 func (poller *fdPoller) close() {
        syscall.Close(poller.pipe[1])
        syscall.Close(poller.pipe[0])
-       syscall.Close(poller.fd)
        syscall.Close(poller.epfd)
 }
index 1c26a294740756b3f8011d3122b6c90c4dbb1b19..9d8e120c51717ed5aad7fab9da0a118771204bfe 100644 (file)
@@ -139,6 +139,7 @@ func TestInotifyCloseCreate(t *testing.T) {
        // Now we try to swap the file descriptor under its nose.
        w.Close()
        w, err = NewWatcher()
+       defer w.Close()
        if err != nil {
                t.Fatalf("Failed to create second watcher: %v", err)
        }