summaryrefslogtreecommitdiff
path: root/inotify/bits.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2015-09-05 13:59:36 -0600
committerLuke Shumaker <lukeshu@sbcglobal.net>2015-09-05 13:59:36 -0600
commitb31d51e0b16f6233f2285adbab674ecfa2ace4ff (patch)
tree027677266bd9865f1ee9bb237853f0cb50da38cd /inotify/bits.go
parent0d064cbe0675f9029b6ac27d12c6f462b18ffe82 (diff)
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.
Diffstat (limited to 'inotify/bits.go')
-rw-r--r--inotify/bits.go15
1 files changed, 14 insertions, 1 deletions
diff --git a/inotify/bits.go b/inotify/bits.go
index 3606b52..9162435 100644
--- a/inotify/bits.go
+++ b/inotify/bits.go
@@ -1,5 +1,7 @@
package inotify
+import "sync/atomic"
+
const (
// Flags for the parameter of InotifyInit1().
// These, oddly, appear to be 24-bit numbers.
@@ -7,8 +9,19 @@ const (
IN_NONBLOCK uint32 = 00004000
)
-type Mask uint32
+// Logically, Fd and Wd should be 'int', not 'int64', to match the OS.
+// But, because there's no 'sync/atomic.SwapInt', we cast up to int64.
+type Wd int64
+type Fd int64
+
+func swapFd(addr *Fd, new Fd) (old Fd) {
+ return Fd(atomic.SwapInt64((*int64)(addr), int64(new)))
+}
+func loadFd(addr *Fd) Fd {
+ return Fd(atomic.LoadInt64((*int64)(addr)))
+}
+type Mask uint32
const (
// Supported events suitable for the `mask` parameter of Inotify.AddWatch().
IN_ACCESS Mask = (1<< 0) // File was accessed.