Skip to content
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

Merged
merged 14 commits into from
Oct 4, 2017
Merged

Some fixes regarding unwatching and rewatching a path #129

merged 14 commits into from
Oct 4, 2017

Conversation

imsodin
Copy link
Contributor

@imsodin imsodin commented Aug 31, 2017

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.

@imsodin
Copy link
Contributor Author

imsodin commented Oct 1, 2017

@rjeczalik Any feedback?
I need this downstream in Syncthing as tests expose some of these bugs. It would be nice if I didn't have to deviate from this repo.

@@ -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 {
Copy link
Owner

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.

Copy link
Contributor Author

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.

Copy link
Owner

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.

Copy link
Contributor Author

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.

Copy link
Owner

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 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Collaborator

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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @ppknap

Copy link
Collaborator

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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @ppknap

Copy link
Collaborator

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 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

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.

@rjeczalik
Copy link
Owner

@imsodin Changes look good to me, except the canonical part in FSEvents watcher. How about we can revert the deletion of it for now?

@rjeczalik
Copy link
Owner

And sorry it took so long 😇

Copy link
Collaborator

@ppknap ppknap left a 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 {
Copy link
Collaborator

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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

}
}

// TODO(pknap) : doc
func (r *readdcw) loopstate(overEx *overlappedEx) {
r.Lock()
defer r.Unlock()
filter := atomic.LoadUint32(&overEx.parent.parent.filter)
Copy link
Collaborator

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.

Copy link
Contributor Author

@imsodin imsodin Oct 2, 2017

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

Copy link
Collaborator

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@imsodin
Copy link
Contributor Author

imsodin commented Oct 3, 2017

@rjeczalik Don't worry about the time - I am just glad to get feedback!

About the canonical stuff see my response to your comment on the code:
#129 (comment)

@imsodin
Copy link
Contributor Author

imsodin commented Oct 4, 2017

About the rebase: I just spotted and undid a changed comment that belongs to #128, everything else did not change.

@rjeczalik rjeczalik merged commit 1aa3b9d into rjeczalik:master Oct 4, 2017
@rjeczalik
Copy link
Owner

Thanks for the fixes and improvements @imsodin!

@Zillode
Copy link
Contributor

Zillode commented Oct 5, 2017

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants