// A Watcher waits for and receives event notifications
// for a specific set of files and directories.
type Watcher struct {
+ mu sync.Mutex // Map access
port syscall.Handle // Handle to completion port
watches watchMap // Map of watches (key: i-number)
fsnFlags map[string]uint32 // Map of watched files to flags used for filter
if err != nil {
return err
}
+ w.mu.Lock()
watchEntry := w.watches.get(ino)
+ w.mu.Unlock()
if watchEntry == nil {
if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil {
syscall.CloseHandle(ino.handle)
path: dir,
names: make(map[string]uint64),
}
+ w.mu.Lock()
w.watches.set(ino, watchEntry)
+ w.mu.Unlock()
flags |= provisional
} else {
syscall.CloseHandle(ino.handle)
if err != nil {
return err
}
+ w.mu.Lock()
watch := w.watches.get(ino)
+ w.mu.Unlock()
if watch == nil {
return fmt.Errorf("can't remove non-existent watch for: %s", pathname)
}
if e := syscall.CloseHandle(watch.ino.handle); e != nil {
w.Error <- os.NewSyscallError("CloseHandle", e)
}
+ w.mu.Lock()
delete(w.watches[watch.ino.volume], watch.ino.index)
+ w.mu.Unlock()
return nil
}
e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0],
if watch == nil {
select {
case ch := <-w.quit:
+ w.mu.Lock()
+ indexes := make([]indexMap, 0)
for _, index := range w.watches {
+ indexes = append(indexes, index)
+ }
+ w.mu.Unlock()
+ for _, index := range indexes {
for _, watch := range index {
w.deleteWatch(watch)
w.startRead(watch)