mirror of
https://github.com/golang/go
synced 2024-11-26 00:07:57 -07:00
exp/inotify: prevent data race
Fixes #3713. R=bradfitz, rsc CC=golang-dev https://golang.org/cl/6331055
This commit is contained in:
parent
5e75337c4e
commit
b3382ec9e9
@ -31,6 +31,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -47,6 +48,7 @@ type watch struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Watcher struct {
|
type Watcher struct {
|
||||||
|
mu sync.Mutex
|
||||||
fd int // File descriptor (as returned by the inotify_init() syscall)
|
fd int // File descriptor (as returned by the inotify_init() syscall)
|
||||||
watches map[string]*watch // Map of inotify watches (key: path)
|
watches map[string]*watch // Map of inotify watches (key: path)
|
||||||
paths map[int]string // Map of watched paths (key: watch descriptor)
|
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
|
watchEntry.flags |= flags
|
||||||
flags |= syscall.IN_MASK_ADD
|
flags |= syscall.IN_MASK_ADD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.mu.Lock() // synchronize with readEvents goroutine
|
||||||
|
|
||||||
wd, err := syscall.InotifyAddWatch(w.fd, path, flags)
|
wd, err := syscall.InotifyAddWatch(w.fd, path, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
w.mu.Unlock()
|
||||||
return &os.PathError{
|
return &os.PathError{
|
||||||
Op: "inotify_add_watch",
|
Op: "inotify_add_watch",
|
||||||
Path: path,
|
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.watches[path] = &watch{wd: uint32(wd), flags: flags}
|
||||||
w.paths[wd] = path
|
w.paths[wd] = path
|
||||||
}
|
}
|
||||||
|
w.mu.Unlock()
|
||||||
return nil
|
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
|
// 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 "Name" field with a valid filename. We retrieve the path of the watch from
|
||||||
// the "paths" map.
|
// the "paths" map.
|
||||||
|
w.mu.Lock()
|
||||||
event.Name = w.paths[int(raw.Wd)]
|
event.Name = w.paths[int(raw.Wd)]
|
||||||
|
w.mu.Unlock()
|
||||||
if nameLen > 0 {
|
if nameLen > 0 {
|
||||||
// Point "bytes" at the first byte of the filename
|
// Point "bytes" at the first byte of the filename
|
||||||
bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
|
bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
|
||||||
|
Loading…
Reference in New Issue
Block a user