Skip to content
This repository has been archived by the owner on Oct 4, 2021. It is now read-only.

Fixes issue #6898 FileWatcherService locks UI Thread on linux. In #6900

Merged
merged 3 commits into from
Jan 18, 2019

Conversation

mkrueger
Copy link
Contributor

conjunction with the mono patch:
mono/mono#12432

I think the mono patch is the real fix here but I optimized the
UpdateWatchers.

conjunction with the mono patch:
mono/mono#12432

I think the mono patch is the real fix here but I optimized the
UpdateWatchers.
@mkrueger mkrueger requested review from Therzok and a team January 15, 2019 14:44
// First remove the watchers, so we don't spin too many threads.
foreach (var directory in toRemove) {
RemoveWatcher_NoLock (directory);
if (newWatchers.Count == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we ever hit this case as a fast path?

Copy link
Contributor

Choose a reason for hiding this comment

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

That would mean that we cleared all the filewatchers, which I don't think will happen often. I would go for simplicity of code here and merge the loop of this and the one below.

newWatchers.Contains (directory) in the second loop below will exit early as the collection has no elements.

Copy link
Contributor Author

@mkrueger mkrueger Jan 16, 2019

Choose a reason for hiding this comment

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

It was in the original code :), therefore I decided not to remove it. But y doesn't make much difference here. The original code over evaluated the cost of Contains/foreach etc. and underestimated LINQ and memory usage. Usually the # of watchers to suspect here is low - way below 1 million where that foreach could be of any impact :).

removed that fast path case

Copy link
Contributor

Choose a reason for hiding this comment

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

We can have up to 8 watchers, due to the algorithm.

@Therzok
Copy link
Contributor

Therzok commented Jan 16, 2019

Okay, I remember why I added the extra list. See test failures:

2019-01-16T08:08:27.6125640Z    System.InvalidOperationException : Collection was modified; enumeration operation may not execute.
2019-01-16T08:08:27.6126540Z   at System.Collections.Generic.Dictionary`2+Enumerator[TKey,TValue].MoveNext () [0x00090] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-08/external/bockbuild/builds/mono-x64/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:1202 
2019-01-16T08:08:27.6126750Z   at MonoDevelop.Projects.FileWatcherService.UpdateWatchers (System.Threading.CancellationToken token) [0x00100] in /Users/vsts/agent/2.144.0/work/1/s/monodevelop/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/FileWatcherService.cs:108 
2019-01-16T08:08:27.6126930Z   at MonoDevelop.Projects.FileWatcherService+<>c__DisplayClass8_0.<UpdateWatchersAsync>b__0 () [0x00000] in /Users/vsts/agent/2.144.0/work/1/s/monodevelop/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/FileWatcherService.cs:79 
2019-01-16T08:08:27.6127780Z   at System.Threading.Tasks.Task.InnerInvoke () [0x0000f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-08/external/bockbuild/builds/mono-x64/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2500 
2019-01-16T08:08:27.6128670Z   at System.Threading.Tasks.Task.Execute () [0x00000] in /Users/builder/jenkins/workspace/build-package-osx-mono/2018-08/external/bockbuild/builds/mono-x64/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2343 
2019-01-16T08:08:27.6129340Z --- End of stack trace from previous location where exception was thrown ---

Also, it looks like the line endings were changed.

The toRemove list can easily be converted to a static field as well -
only used in a static method inside a lock without a way of recursion.
static HashSet<FilePath> newWatchers = new HashSet<FilePath>();

static HashSet<FilePath> newWatchers = new HashSet<FilePath>();
static List<FilePath> toRemove = new List<FilePath> ();
Copy link
Contributor

Choose a reason for hiding this comment

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

toRemove is never cleared

Copy link
Contributor

@Therzok Therzok left a comment

Choose a reason for hiding this comment

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

It is, misread.

@Therzok Therzok merged commit 02b2ca3 into master Jan 18, 2019
@Therzok Therzok deleted the master-issue6898 branch January 18, 2019 23:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants