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

src: make FSEventWrap/StatWatcher::Start more robust #17432

Closed
wants to merge 1 commit into from

Conversation

TimothyGu
Copy link
Member

Fixes: #17430

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

fs, src

@TimothyGu TimothyGu added the fs Issues and PRs related to the fs subsystem / file system. label Dec 3, 2017
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. fs Issues and PRs related to the fs subsystem / file system. labels Dec 3, 2017
@TimothyGu
Copy link
Member Author

CHECK_EQ(wrap->initialized_, false);
if (wrap->initialized_) {
args.GetReturnValue().Set(0);
return;
Copy link
Member

Choose a reason for hiding this comment

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

For consistency with the surrounding code, maybe write this as return args.GetReturnValue().Set(0); without braces.

@@ -64,6 +64,8 @@ for (const testCase of cases) {
assert.strictEqual(eventType, 'change');
assert.strictEqual(argFilename, testCase.fileName);

watcher.start(); // should not crash
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't the linter complain about using two spaces before //?

Copy link
Member Author

Choose a reason for hiding this comment

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

No it doesn't, though fixed anyway.

@@ -111,6 +111,8 @@ void StatWatcher::Start(const FunctionCallbackInfo<Value>& args) {
const bool persistent = args[1]->BooleanValue();
const uint32_t interval = args[2]->Uint32Value();

if (uv_is_active(reinterpret_cast<uv_handle_t*>(wrap->watcher_)))
return;
Copy link
Member

Choose a reason for hiding this comment

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

This is wrong when Start() is called with different arguments than last time. This should work:

uv_fs_poll_stop(wrap->watcher_);
uv_fs_poll_start(wrap->watcher_, Callback, *path, interval);

// Safe, uv_ref/uv_unref are idempotent.
if (persistent)
  uv_ref(reinterpret_cast<uv_handle_t*>(wrap->watcher_));
else
  uv_unref(reinterpret_cast<uv_handle_t*>(wrap->watcher_));

And while we're here, this code really ought to check the return value of uv_fs_poll_start() (and uv_fs_poll_stop() too, although it can't fail in the current implementation.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Start() is not part of the external API, and no guarantees were made whether it works with different arguments or not. On the other hand, the proposed solution breaks compatibility.

Copy link
Member

Choose a reason for hiding this comment

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

Then why don't you make it throw an exception? Methods should not silently do the wrong thing, that's arguably worse than aborting.

On the other hand, the proposed solution breaks compatibility.

In what way?

Copy link
Member Author

Choose a reason for hiding this comment

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

The added test currently throws no exception. If I make it throw an exception it would be breaking compatibility.

Copy link
Member

Choose a reason for hiding this comment

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

What do you mean? There are no compatibility issues because it was aborting before.

Copy link
Member Author

Choose a reason for hiding this comment

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

It was aborting in FSEventWrap, not StatWatcher. This was simply tacked on as a similar change that improves the current behavior in a similar way.

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't use the word 'improves'. StatWatcher already worked mostly like I proposed in my first comment and that would be an acceptable change for FSEventWrap too, as would throwing an exception. Silently ignoring changes is the worst possible solution however.

@TimothyGu TimothyGu force-pushed the fswatcher-robustify branch from 924f5f6 to b4fd89e Compare December 3, 2017 20:55
@BridgeAR
Copy link
Member

@BridgeAR BridgeAR added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Dec 12, 2017
addaleax pushed a commit to addaleax/node that referenced this pull request Dec 13, 2017
@addaleax
Copy link
Member

Landed in cd71fc1

@addaleax addaleax closed this Dec 13, 2017
@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Dec 13, 2017
@bnoordhuis
Copy link
Member

#17432 (comment) is still unfixed.

@TimothyGu TimothyGu deleted the fswatcher-robustify branch December 13, 2017 07:54
MylesBorins pushed a commit that referenced this pull request Jan 8, 2018
@MylesBorins MylesBorins mentioned this pull request Jan 10, 2018
@MylesBorins
Copy link
Contributor

should this be backported to v6.x or 8.x... my gut is no but not 100%

@MylesBorins
Copy link
Contributor

ping re: backport

@MylesBorins
Copy link
Contributor

MylesBorins commented May 22, 2018

ping re: backport

edit: landed cleanly on 8.x. Any reason not to land?

MylesBorins pushed a commit that referenced this pull request May 22, 2018
@TimothyGu
Copy link
Member Author

@MylesBorins No, not really.

MylesBorins pushed a commit that referenced this pull request Jun 14, 2018
@MylesBorins MylesBorins mentioned this pull request Jul 9, 2018
rvagg pushed a commit that referenced this pull request Aug 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Undocumented fs.FSWatcher::start() trips assertion in FSEventWrap::Start
7 participants