From b31d51e0b16f6233f2285adbab674ecfa2ace4ff Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 5 Sep 2015 13:59:36 -0600 Subject: inotify: Avoid most of the race conditions, get rid of Cint There's still a condition that could be a race with fd-reuse, if one goroutine is calling inotify.{AddWatch,RmWatch,Read}(); another goroutine is calling inotify.Close(), and several things happen between loadFd() running and the add_watch/rm_watch/read syscall launching: - syscall.Close() returns - syscall.Open() reuses the filedescriptor A B syscall(loadFd()) inotify.Close(); syscall.Open() ---------------------------------------------------------- loadFd() syscall.Close() syscall.Open() syscall() Given that Read() can't be allowed to block Close() from running, I'm not sure there's a way to fix this. --- inotify/syscall.go | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'inotify/syscall.go') diff --git a/inotify/syscall.go b/inotify/syscall.go index 1b5c426..721a10a 100644 --- a/inotify/syscall.go +++ b/inotify/syscall.go @@ -1,14 +1,11 @@ package inotify import ( - "C" "os" "syscall" ) -type Cint C.int - -func pathError(op string, path string, err error) error { +func newPathError(op string, path string, err error) error { if err == nil { return nil } @@ -16,26 +13,26 @@ func pathError(op string, path string, err error) error { } /* Create and initialize inotify instance. */ -func inotify_init() (Cint, error) { +func inotify_init() (Fd, error) { fd, errno := syscall.InotifyInit() - return Cint(fd), os.NewSyscallError("inotify_init", errno) + return Fd(fd), os.NewSyscallError("inotify_init", errno) } /* Create and initialize inotify instance. */ -func inotify_init1(flags Cint) (Cint, error) { - fd, errno := syscall.InotifyInit1(int(flags)) - return Cint(fd), os.NewSyscallError("inotify_init1", errno) +func inotify_init1(flags int) (Fd, error) { + fd, errno := syscall.InotifyInit1(flags) + return Fd(fd), os.NewSyscallError("inotify_init1", errno) } /* Add watch of object NAME to inotify instance FD. Notify about events specified by MASK. */ -func inotify_add_watch(fd Cint, name string, mask uint32) (Cint, error) { - wd, errno := syscall.InotifyAddWatch(int(fd), name, mask) - return Cint(wd), pathError("inotify_add_watch", name, errno) +func inotify_add_watch(fd Fd, name string, mask Mask) (Wd, error) { + wd, errno := syscall.InotifyAddWatch(int(fd), name, uint32(mask)) + return Wd(wd), newPathError("inotify_add_watch", name, errno) } /* Remove the watch specified by WD from the inotify instance FD. */ -func inotify_rm_watch(fd Cint, wd Cint) error { +func inotify_rm_watch(fd Fd, wd Wd) error { success, errno := syscall.InotifyRmWatch(int(fd), uint32(wd)) switch success { case -1: @@ -52,11 +49,11 @@ func inotify_rm_watch(fd Cint, wd Cint) error { panic("should never happen") } -func sysclose(fd Cint) error { +func sysclose(fd Fd) error { return os.NewSyscallError("close", syscall.Close(int(fd))) } -func sysread(fd Cint, p []byte) (Cint, error) { +func sysread(fd Fd, p []byte) (int, error) { n, err := syscall.Read(int(fd), p) - return Cint(n), os.NewSyscallError("read", err) + return n, os.NewSyscallError("read", err) } -- cgit v1.2.3