-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some fixes regarding unwatching and rewatching a path #129
Conversation
@rjeczalik Any feedback? |
@@ -189,9 +187,6 @@ func newWatcher(c chan<- EventInfo) watcher { | |||
} | |||
|
|||
func (fse *fsevents) watch(path string, event Event, isrec int32) (err error) { | |||
if path, err = canonical(path); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can remove this yet, until the functionality is moved to tree.
Morever I think it'd need to stay here because of fse.watches
- if we put a watch on a dir and a symlink to it, fse.watches
must not hold two watches but only one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it already in the tree:
https://github.com/rjeczalik/notify/blob/master/tree_recursive.go#L164
Cleanpath subsequently calls canonical on the path and no other watcher implementation uses canonical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, but fse.watches
maintains its own path -> watches mapping, if we get rid of canonical, we may have duplicated watches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't understand it: The paths in fse.watches
that were previously passed through canonical are those given as arguments to the exported (Recursive-)Re-/Watch functions, which are called from the tree, where the paths were already canonicalized in the tree - how else can duplicated paths enter fse.watches
?
Other watchers maintains such a map of paths to structs as well, but don't canonicalize paths (e.g. readdcw in r.m
, trigger in pthLkp
).
Also the new tests fail when canonical
is reintroduced, as it won't remove a non-existing path, because canonical
stats the path and thus fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which are called from the tree, where the paths were already canonicalized in the tree
You're right, I take back my comment about duplicates - canonical is not needed here.
Also the new tests fail when canonical is reintroduced, as it won't remove a non-existing path, because canonical stats the path and thus fails.
Good point.
|
||
// if path was removed, notify already removed the watch and returns EINVAL error | ||
func removeInotifyWatch(fd int32, iwd int32) (err error) { | ||
if _, err = unix.InotifyRmWatch(int(fd), uint32(iwd)); err != nil && err != unix.EINVAL { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
r.loopevent(n, overEx) | ||
if err = overEx.parent.readDirChanges(); err != nil { | ||
// TODO: error handling | ||
} | ||
} | ||
r.loopstate(overEx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/cc @ppknap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/cc @ppknap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -56,6 +57,19 @@ type trigger interface { | |||
IsStop(n interface{}, err error) bool | |||
} | |||
|
|||
// trgWatched is a the base data structure representing watched file/directory. | |||
// The platform specific full data structure (watched) must embed this type. | |||
type trgWatched struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/cc @pblaszczyk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Pawel's review is not needed here since this struct is just a "base" for watched
type from Kqueue's and FEN impls.
@imsodin Changes look good to me, except the |
And sorry it took so long 😇 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, @imsodin thank you for spending time on this!
|
||
// if path was removed, notify already removed the watch and returns EINVAL error | ||
func removeInotifyWatch(fd int32, iwd int32) (err error) { | ||
if _, err = unix.InotifyRmWatch(int(fd), uint32(iwd)); err != nil && err != unix.EINVAL { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
r.loopevent(n, overEx) | ||
if err = overEx.parent.readDirChanges(); err != nil { | ||
// TODO: error handling | ||
} | ||
} | ||
r.loopstate(overEx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
watcher_readdcw.go
Outdated
} | ||
} | ||
|
||
// TODO(pknap) : doc | ||
func (r *readdcw) loopstate(overEx *overlappedEx) { | ||
r.Lock() | ||
defer r.Unlock() | ||
filter := atomic.LoadUint32(&overEx.parent.parent.filter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably we won't need atomic
here anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably the same in nonStateWatched
, as it is only called when the lock is held, right?
https://github.com/rjeczalik/notify/pull/129/files/45213bd71c5145dd70d258df0acaf721b59a7d90#diff-ac809f36d763355597370ab566b6d71aR478
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed 👍 🥇
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@rjeczalik Don't worry about the time - I am just glad to get feedback! About the |
About the rebase: I just spotted and undid a changed comment that belongs to #128, everything else did not change. |
Thanks for the fixes and improvements @imsodin! |
👍 |
This started in issue #124 and replaces the previously split up PRs. This is bundled as the fixed problems come up in the same tests, but are in separate commits to make each change-diff about a single problem. The commits should explain what is going on.