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)
// 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),
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
}
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
}
defer close(w.doneresp)
defer close(w.Errors)
defer close(w.Events)
+ defer syscall.Close(w.fd)
defer w.poller.close()
for {
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"
// 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
}
}
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])
}
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])
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)
}