Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Ungureanu <therzok@gmail.com>2018-03-28 18:25:47 +0300
committerMarius Ungureanu <teromario@yahoo.com>2018-04-17 14:13:26 +0300
commit06dc79bb42e6c5d55dc73e9786b36ad7353f333c (patch)
tree1bd427520babebaa11922f7bb966634a8acc728d /main/src/core
parentd2f7eef570898e21b901b68898fa8c656fe4c40b (diff)
[Core] Reduce lock contention on imported files
This reduces lock contention on imported files by not locking on the global project info dictionary when accessing it, instead locking on each project info. This should help with concurrent imports of different imported files
Diffstat (limited to 'main/src/core')
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs63
1 files changed, 40 insertions, 23 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
index 5ead0ee69e..0e1ac4c2ad 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
@@ -47,6 +47,8 @@ namespace MonoDevelop.Projects.MSBuild
public MSBuildProject Project;
public DateTime LastWriteTime;
public int ReferenceCount = 1;
+ public bool NeedsLoad = false;
+ public object LockObject = new object ();
}
class ProjectInfo
@@ -130,38 +132,53 @@ namespace MonoDevelop.Projects.MSBuild
MSBuildProject LoadProject (MSBuildEvaluationContext context, FilePath fileName)
{
fileName = fileName.CanonicalPath;
+
+ LoadedProjectInfo pi;
lock (loadedProjects) {
- LoadedProjectInfo pi;
- if (loadedProjects.TryGetValue (fileName, out pi)) {
- pi.ReferenceCount++;
- var lastWriteTime = File.GetLastWriteTime (fileName);
- if (pi.LastWriteTime != lastWriteTime) {
- pi.LastWriteTime = lastWriteTime;
- pi.Project.Load (fileName, new MSBuildXmlReader { ForEvaluation = true });
- }
- return pi.Project;
+ if (!loadedProjects.TryGetValue (fileName, out pi)) {
+ loadedProjects [fileName] = pi = new LoadedProjectInfo ();
}
- LogBeginProjectFileLoad (context, fileName);
- MSBuildProject p = new MSBuildProject (EngineManager);
- p.Load (fileName, new MSBuildXmlReader { ForEvaluation = true });
- loadedProjects [fileName] = new LoadedProjectInfo { Project = p, LastWriteTime = File.GetLastWriteTime (fileName) };
- LogEndProjectFileLoad (context);
- return p;
+ pi.ReferenceCount++;
+ }
+
+ lock (pi.LockObject) {
+ if (pi.Project == null) {
+ pi.Project = new MSBuildProject (EngineManager);
+ pi.NeedsLoad = true;
+ }
+ }
+
+ lock (pi.LockObject) {
+ if (!pi.NeedsLoad)
+ pi.NeedsLoad = pi.LastWriteTime != File.GetLastWriteTimeUtc (fileName);
+
+ if (pi.NeedsLoad) {
+ LogBeginProjectFileLoad (context, fileName);
+ pi.Project.Load (fileName, new MSBuildXmlReader { ForEvaluation = true });
+ pi.NeedsLoad = false;
+ pi.LastWriteTime = File.GetLastWriteTimeUtc (fileName);
+ LogEndProjectFileLoad (context);
+ }
+
+ return pi.Project;
}
}
void UnloadProject (MSBuildProject project)
{
var fileName = project.FileName.CanonicalPath;
+ LoadedProjectInfo pi;
lock (loadedProjects) {
- LoadedProjectInfo pi;
- if (loadedProjects.TryGetValue (fileName, out pi)) {
- pi.ReferenceCount--;
- if (pi.ReferenceCount == 0) {
- loadedProjects.Remove (fileName);
- project.Dispose ();
- //Console.WriteLine ("Unloaded: " + fileName);
- }
+ if (!loadedProjects.TryGetValue (fileName, out pi))
+ return;
+
+ pi.ReferenceCount--;
+ if (pi.ReferenceCount == 0) {
+ loadedProjects.Remove (fileName);
+ lock (pi.LockObject)
+ pi.Project = null;
+ project.Dispose ();
+ //Console.WriteLine ("Unloaded: " + fileName);
}
}
}