diff options
Diffstat (limited to 'vendor/github.com/rjeczalik/notify/watcher_readdcw.go')
-rw-r--r-- | vendor/github.com/rjeczalik/notify/watcher_readdcw.go | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/vendor/github.com/rjeczalik/notify/watcher_readdcw.go b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go index 5923bfdda..1494fcd79 100644 --- a/vendor/github.com/rjeczalik/notify/watcher_readdcw.go +++ b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go @@ -284,16 +284,18 @@ func (r *readdcw) watch(path string, event Event, recursive bool) (err error) { return } r.Lock() + defer r.Unlock() if wd, ok = r.m[path]; ok { - r.Unlock() + dbgprint("watch: exists already") return } if wd, err = newWatched(r.cph, uint32(event), recursive, path); err != nil { - r.Unlock() return } r.m[path] = wd - r.Unlock() + dbgprint("watch: new watch added") + } else { + dbgprint("watch: exists already") } return nil } @@ -337,33 +339,32 @@ func (r *readdcw) loop() { continue } overEx := (*overlappedEx)(unsafe.Pointer(overlapped)) - if n == 0 { - r.loopstate(overEx) - } else { + if n != 0 { r.loopevent(n, overEx) if err = overEx.parent.readDirChanges(); err != nil { // TODO: error handling } } + r.loopstate(overEx) } } // TODO(pknap) : doc func (r *readdcw) loopstate(overEx *overlappedEx) { - filter := atomic.LoadUint32(&overEx.parent.parent.filter) + r.Lock() + defer r.Unlock() + filter := overEx.parent.parent.filter if filter&onlyMachineStates == 0 { return } if overEx.parent.parent.count--; overEx.parent.parent.count == 0 { switch filter & onlyMachineStates { case stateRewatch: - r.Lock() + dbgprint("loopstate rewatch") overEx.parent.parent.recreate(r.cph) - r.Unlock() case stateUnwatch: - r.Lock() + dbgprint("loopstate unwatch") delete(r.m, syscall.UTF16ToString(overEx.parent.pathw)) - r.Unlock() case stateCPClose: default: panic(`notify: windows loopstate logic error`) @@ -450,8 +451,8 @@ func (r *readdcw) rewatch(path string, oldevent, newevent uint32, recursive bool } var wd *watched r.Lock() - if wd, err = r.nonStateWatched(path); err != nil { - r.Unlock() + defer r.Unlock() + if wd, err = r.nonStateWatchedLocked(path); err != nil { return } if wd.filter&(onlyNotifyChanges|onlyNGlobalEvents) != oldevent { @@ -462,21 +463,19 @@ func (r *readdcw) rewatch(path string, oldevent, newevent uint32, recursive bool if err = wd.closeHandle(); err != nil { wd.filter = oldevent wd.recursive = recursive - r.Unlock() return } - r.Unlock() return } // TODO : pknap -func (r *readdcw) nonStateWatched(path string) (wd *watched, err error) { +func (r *readdcw) nonStateWatchedLocked(path string) (wd *watched, err error) { wd, ok := r.m[path] if !ok || wd == nil { err = errors.New(`notify: ` + path + ` path is unwatched`) return } - if filter := atomic.LoadUint32(&wd.filter); filter&onlyMachineStates != 0 { + if wd.filter&onlyMachineStates != 0 { err = errors.New(`notify: another re/unwatching operation in progress`) return } @@ -497,17 +496,26 @@ func (r *readdcw) RecursiveUnwatch(path string) error { func (r *readdcw) unwatch(path string) (err error) { var wd *watched r.Lock() - if wd, err = r.nonStateWatched(path); err != nil { - r.Unlock() + defer r.Unlock() + if wd, err = r.nonStateWatchedLocked(path); err != nil { return } wd.filter |= stateUnwatch if err = wd.closeHandle(); err != nil { wd.filter &^= stateUnwatch - r.Unlock() return } - r.Unlock() + if _, attrErr := syscall.GetFileAttributes(&wd.pathw[0]); attrErr != nil { + for _, g := range wd.digrip { + if g != nil { + dbgprint("unwatch: posting") + if err = syscall.PostQueuedCompletionStatus(r.cph, 0, 0, (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped))); err != nil { + wd.filter &^= stateUnwatch + return + } + } + } + } return } |