From: Jan Ziak <0xe2.0x9a.0x9b@gmail.com> Date: Mon, 25 Jun 2012 18:08:09 +0000 (-0400) Subject: exp/inotify: prevent data race X-Git-Tag: go1.1rc2~2890 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b3382ec9e9cfbb20efd7bf7d6a369071a46c8dfe;p=gostls13.git exp/inotify: prevent data race Fixes #3713. R=bradfitz, rsc CC=golang-dev https://golang.org/cl/6331055 --- diff --git a/src/pkg/exp/inotify/inotify_linux.go b/src/pkg/exp/inotify/inotify_linux.go index 912cf5db82..f989a9224d 100644 --- a/src/pkg/exp/inotify/inotify_linux.go +++ b/src/pkg/exp/inotify/inotify_linux.go @@ -31,6 +31,7 @@ import ( "fmt" "os" "strings" + "sync" "syscall" "unsafe" ) @@ -47,6 +48,7 @@ type watch struct { } type Watcher struct { + mu sync.Mutex fd int // File descriptor (as returned by the inotify_init() syscall) watches map[string]*watch // Map of inotify watches (key: path) paths map[int]string // Map of watched paths (key: watch descriptor) @@ -105,8 +107,12 @@ func (w *Watcher) AddWatch(path string, flags uint32) error { watchEntry.flags |= flags flags |= syscall.IN_MASK_ADD } + + w.mu.Lock() // synchronize with readEvents goroutine + wd, err := syscall.InotifyAddWatch(w.fd, path, flags) if err != nil { + w.mu.Unlock() return &os.PathError{ Op: "inotify_add_watch", Path: path, @@ -118,6 +124,7 @@ func (w *Watcher) AddWatch(path string, flags uint32) error { w.watches[path] = &watch{wd: uint32(wd), flags: flags} w.paths[wd] = path } + w.mu.Unlock() return nil } @@ -187,7 +194,9 @@ func (w *Watcher) readEvents() { // doesn't append the filename to the event, but we would like to always fill the // the "Name" field with a valid filename. We retrieve the path of the watch from // the "paths" map. + w.mu.Lock() event.Name = w.paths[int(raw.Wd)] + w.mu.Unlock() if nameLen > 0 { // Point "bytes" at the first byte of the filename bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))