From 25bd684ed100d303284ea20fa9a662252e83332b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Nivet?= Date: Mon, 5 Feb 2018 11:43:05 +0100 Subject: [PATCH 1/2] - Fix concurrency issue regression: When code has been moved from targets to csharp in commit c3354facaed77ea42f6ac081f28325ad7cab70da file read has been excluded from the mutex which produce concurrency issue like explain in the comment above the mutex creation - Reduce scope of the mutex to optimize parallel compilations This is a really interesting proposition from issue #36 --- .../NugetPackageManager.cs | 52 +++++++++---------- .../Baseclass.Contrib.Nuget.Output.nuspec | 4 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs b/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs index dd4f33b..95e4a28 100644 --- a/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs +++ b/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs @@ -72,40 +72,40 @@ public bool TryGetUsedPackagesDependendingOnNugetOutput(out ITaskItem[] packages // use a mutex to ensure that only one process unzip the nuspec // and that one process do not start reading it due to its existence while another one is still writing it. - if (!File.Exists(nugetSpec)) + var mut = new Mutex(false, nugetSpec); + var xml = new XmlDocument(); + try { - var mut = new Mutex(false, "UnzipNuSpec"); - try - { - mut.WaitOne(); + mut.WaitOne(); - if (!File.Exists(nugetSpec)) - try + if (!File.Exists(nugetSpec)) + { + try + { + using ( + var outputstream = new FileStream(nugetSpec, FileMode.Create, + FileAccess.ReadWrite, FileShare.None)) { - using ( - var outputstream = new FileStream(nugetSpec, FileMode.Create, - FileAccess.ReadWrite, FileShare.None)) + using (var nspecstream = nuspec.GetStream()) { - using (var nspecstream = nuspec.GetStream()) - { - nspecstream.CopyTo(outputstream); - } + nspecstream.CopyTo(outputstream); } } - catch (IOException) - { - if (!File.Exists(nugetSpec)) - throw; - } - } - finally - { - mut.ReleaseMutex(); + } + catch (IOException) + { + if (!File.Exists(nugetSpec)) + throw; + } } - } - var xml = new XmlDocument(); - xml.LoadXml(File.ReadAllText(nugetSpec)); + xml.Load(nugetSpec); + } + finally + { + mut.ReleaseMutex(); + } + var deps = xml.GetElementsByTagName("dependency"); foreach (XmlNode dep in deps) { diff --git a/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.nuspec b/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.nuspec index b1318df..e6a8eb6 100644 --- a/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.nuspec +++ b/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.nuspec @@ -10,8 +10,8 @@ http://www.baseclass.ch/Contrib/Nuget false Treats the "output" folder in an dependend nuget package as an additional special folder and copies it's content to the build folder - - Added support for paket -- Added support for repository path configuration + - Fix concurrency issue regression +- Reduce scope of the mutex to optimize parallel compilations Nuget Targets Copy Output build package convention From 5c30b89a5dd2c19a71b43e95adcaac2fafb64a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Nivet?= Date: Tue, 6 Feb 2018 15:29:53 +0100 Subject: [PATCH 2/2] Change key of the Mutex to the filename instead of the full path of the file Mutex constructor search for the file when we provide a full path as a mutex name... --- .../NugetPackageManager.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs b/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs index 95e4a28..317c23b 100644 --- a/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs +++ b/Baseclass.Contrib.Nuget.Output/Baseclass.Contrib.Nuget.Output.Build/NugetPackageManager.cs @@ -68,11 +68,12 @@ public bool TryGetUsedPackagesDependendingOnNugetOutput(out ITaskItem[] packages using (var archive = Package.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { var nuspec = archive.GetParts().Single(part => part.Uri.ToString().EndsWith(".nuspec")); - var nugetSpec = Path.Combine(nupkgpath, Path.GetFileName(nuspec.Uri.ToString())); + var nuspecFilename = Path.GetFileName(nuspec.Uri.ToString()); + var nugetSpec = Path.Combine(nupkgpath, nuspecFilename); // use a mutex to ensure that only one process unzip the nuspec // and that one process do not start reading it due to its existence while another one is still writing it. - var mut = new Mutex(false, nugetSpec); + var mut = new Mutex(false, nuspecFilename); var xml = new XmlDocument(); try {