diff options
author | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-04-28 22:09:45 +0300 |
---|---|---|
committer | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-04-28 22:09:45 +0300 |
commit | 639695caaa85c866fc91d72551064e653cc276d8 (patch) | |
tree | beac1a4ffce687604682709ffea75b59419c6710 /main/src/core/MonoDevelop.Projects.Formats.MSBuild | |
parent | bf18b85bd44ac61ee85f0e04e764b392889697ea (diff) |
[Core] Add support for cancelling MSBuild builds
Diffstat (limited to 'main/src/core/MonoDevelop.Projects.Formats.MSBuild')
11 files changed, 186 insertions, 146 deletions
diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj index 6e56a94fd8..f5a8db28bc 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj @@ -53,6 +53,7 @@ <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.Shared.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\BuildEngine.Shared.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj index d6a24cbced..ef167e2e04 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj @@ -63,6 +63,7 @@ <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.Shared.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\BuildEngine.Shared.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj index 06519793d6..04e52fc51a 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj @@ -56,6 +56,7 @@ <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.Shared.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\BuildEngine.Shared.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj index f51652a4ed..bc8fcf33fa 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj @@ -55,6 +55,7 @@ <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.Shared.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\BuildEngine.Shared.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.Shared.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.Shared.cs new file mode 100644 index 0000000000..00b66f2616 --- /dev/null +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.Shared.cs @@ -0,0 +1,174 @@ +// +// ProjectBuilder.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Runtime.Remoting; +using System.Collections.Generic; +using Microsoft.Build.BuildEngine; +using System.Globalization; +using System.IO; + +//this is the builder for the deprecated build engine API +#pragma warning disable 618 + +namespace MonoDevelop.Projects.Formats.MSBuild +{ + partial class BuildEngine: MarshalByRefObject, IBuildEngine + { + static readonly AutoResetEvent workDoneEvent = new AutoResetEvent (false); + static ThreadStart workDelegate; + static readonly object workLock = new object (); + static Thread workThread; + static Exception workError; + + static List<int> cancelledTasks = new List<int> (); + static int currentTaskId; + + readonly ManualResetEvent doneEvent = new ManualResetEvent (false); + + public void Dispose () + { + doneEvent.Set (); + } + + internal WaitHandle WaitHandle { + get { return doneEvent; } + } + + public void Ping () + { + } + + public override object InitializeLifetimeService () + { + return null; + } + + public void CancelTask (int taskId) + { + lock (cancelledTasks) { + if (currentTaskId == taskId) + AbortCurrentTask (); + else + cancelledTasks.Add (taskId); + } + } + + static bool IsTaskCancelled (int taskId) + { + lock (cancelledTasks) { + return cancelledTasks.Contains (taskId); + } + } + + static bool SetCurrentTask (int taskId) + { + lock (cancelledTasks) { + if (cancelledTasks.Contains (taskId)) + return false; + currentTaskId = taskId; + return true; + } + } + + static void ResetCurrentTask () + { + lock (cancelledTasks) { + currentTaskId = -1; + } + } + + static void AbortCurrentTask () + { + workThread.Abort (); + workThread = null; + workDoneEvent.Set (); + } + + internal static void RunSTA (ThreadStart ts) + { + RunSTA (-1, ts); + } + + internal static void RunSTA (int taskId, ThreadStart ts) + { + lock (workLock) { + if (IsTaskCancelled (taskId)) + return; + lock (threadLock) { + // Last chance to check for canceled task before the thread is started + if (IsTaskCancelled (taskId)) + return; + + workDelegate = ts; + workError = null; + if (workThread == null) { + workThread = new Thread (STARunner); + workThread.SetApartmentState (ApartmentState.STA); + workThread.IsBackground = true; + workThread.CurrentUICulture = uiCulture; + workThread.Start (); + } + else + // Awaken the existing thread + Monitor.Pulse (threadLock); + } + if (!SetCurrentTask (taskId)) { + // The task was aborted after all. Since the thread is already running we need to abort it + AbortCurrentTask (); + return; + } + + workDoneEvent.WaitOne (); + + ResetCurrentTask (); + } + if (workError != null) + throw new Exception ("MSBuild operation failed", workError); + } + + static readonly object threadLock = new object (); + + static void STARunner () + { + lock (threadLock) { + do { + try { + workDelegate (); + } + catch (Exception ex) { + workError = ex; + } + workDoneEvent.Set (); + } + while (Monitor.Wait (threadLock, 60000)); + + workThread = null; + } + } + } +}
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs index b8d08a7437..61dc37af7d 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs @@ -25,45 +25,23 @@ // THE SOFTWARE. using System; -using System.Threading; using System.Runtime.Remoting; using System.Collections.Generic; using Microsoft.Build.BuildEngine; using System.Globalization; -using System.IO; //this is the builder for the deprecated build engine API #pragma warning disable 618 namespace MonoDevelop.Projects.Formats.MSBuild { - public class BuildEngine: MarshalByRefObject, IBuildEngine + public partial class BuildEngine: MarshalByRefObject, IBuildEngine { - static readonly AutoResetEvent workDoneEvent = new AutoResetEvent (false); - static ThreadStart workDelegate; - static readonly object workLock = new object (); - static Thread workThread; static CultureInfo uiCulture; - static Exception workError; - - readonly ManualResetEvent doneEvent = new ManualResetEvent (false); readonly Dictionary<string,string> unsavedProjects = new Dictionary<string, string> (); internal readonly Engine Engine = new Engine { DefaultToolsVersion = MSBuildConsts.Version }; - public void Dispose () - { - doneEvent.Set (); - } - - internal WaitHandle WaitHandle { - get { return doneEvent; } - } - - public void Ping () - { - } - public void SetCulture (CultureInfo uiCulture) { BuildEngine.uiCulture = uiCulture; @@ -88,11 +66,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild RemotingServices.Disconnect ((MarshalByRefObject) pb); } - public override object InitializeLifetimeService () - { - return null; - } - internal void UnloadProject (string file) { lock (unsavedProjects) @@ -119,48 +92,5 @@ namespace MonoDevelop.Projects.Formats.MSBuild return content; } } - - internal static void RunSTA (ThreadStart ts) - { - lock (workLock) { - lock (threadLock) { - workDelegate = ts; - workError = null; - if (workThread == null) { - workThread = new Thread (STARunner); - workThread.SetApartmentState (ApartmentState.STA); - workThread.IsBackground = true; - workThread.CurrentUICulture = uiCulture; - workThread.Start (); - } - else - // Awaken the existing thread - Monitor.Pulse (threadLock); - } - workDoneEvent.WaitOne (); - } - if (workError != null) - throw new Exception ("MSBuild operation failed", workError); - } - - static readonly object threadLock = new object (); - - static void STARunner () - { - lock (threadLock) { - do { - try { - workDelegate (); - } - catch (Exception ex) { - workError = ex; - } - workDoneEvent.Set (); - } - while (Monitor.Wait (threadLock, 60000)); - - workThread = null; - } - } } }
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs index aa6c02fa13..e69d3b275a 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs @@ -36,33 +36,12 @@ using System.Globalization; namespace MonoDevelop.Projects.Formats.MSBuild
{
- public class BuildEngine: MarshalByRefObject, IBuildEngine
+ public partial class BuildEngine: MarshalByRefObject, IBuildEngine
{
- static readonly AutoResetEvent workDoneEvent = new AutoResetEvent (false);
- static ThreadStart workDelegate;
- static readonly object workLock = new object ();
- static Thread workThread;
static CultureInfo uiCulture;
- static Exception workError;
-
- readonly ManualResetEvent doneEvent = new ManualResetEvent (false);
readonly Dictionary<string, string> unsavedProjects = new Dictionary<string, string> ();
-
readonly ProjectCollection engine = new ProjectCollection { DefaultToolsVersion = MSBuildConsts.Version }; - public void Dispose ()
- {
- doneEvent.Set ();
- }
-
- internal WaitHandle WaitHandle {
- get { return doneEvent; }
- }
-
- public void Ping ()
- {
- }
-
public void SetCulture (CultureInfo uiCulture) {
BuildEngine.uiCulture = uiCulture;
@@ -99,11 +78,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild return content;
}
} -
- public override object InitializeLifetimeService ()
- {
- return null;
- }
internal void UnloadProject (string file)
{
@@ -118,48 +92,5 @@ namespace MonoDevelop.Projects.Formats.MSBuild engine.UnloadAllProjects();
});
}
-
- internal static void RunSTA (ThreadStart ts)
- {
- lock (workLock) {
- lock (threadLock) {
- workDelegate = ts;
- workError = null;
- if (workThread == null) {
- workThread = new Thread (STARunner);
- workThread.SetApartmentState (ApartmentState.STA);
- workThread.IsBackground = true;
- workThread.CurrentUICulture = uiCulture;
- workThread.Start ();
- }
- else
- // Awaken the existing thread
- Monitor.Pulse (threadLock);
- }
- workDoneEvent.WaitOne ();
- }
- if (workError != null)
- throw new Exception ("MSBuild operation failed", workError);
- }
-
- static readonly object threadLock = new object ();
-
- static void STARunner ()
- {
- lock (threadLock) {
- do {
- try {
- workDelegate ();
- }
- catch (Exception ex) {
- workError = ex;
- }
- workDoneEvent.Set ();
- }
- while (Monitor.Wait (threadLock, 60000));
-
- workThread = null;
- }
- }
}
}
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs index 95e8af6d80..60b1172476 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs @@ -37,5 +37,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild IProjectBuilder LoadProject (string projectFile); void UnloadProject (IProjectBuilder pb); void Ping (); + void CancelTask (int taskId); } } diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs index 5740d0391c..a7edbc3c94 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs @@ -36,7 +36,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild void RefreshWithContent (string projectContent); MSBuildResult Run ( ProjectConfigurationInfo[] configurations, ILogWriter logWriter, MSBuildVerbosity verbosity, - string[] runTargets, string[] evaluateItems, string[] evaluateProperties + string[] runTargets, string[] evaluateItems, string[] evaluateProperties, int taskId ); } diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs index 63fdb068b1..4b6c84ea0d 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs @@ -61,10 +61,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild public MSBuildResult Run ( ProjectConfigurationInfo[] configurations, ILogWriter logWriter, MSBuildVerbosity verbosity, - string[] runTargets, string[] evaluateItems, string[] evaluateProperties) + string[] runTargets, string[] evaluateItems, string[] evaluateProperties, int taskId) { MSBuildResult result = null; - BuildEngine.RunSTA (delegate { + BuildEngine.RunSTA (taskId, delegate { try { var project = SetupProject (configurations);
currentLogWriter = logWriter;
diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs index c6b80d80a9..14498e6461 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs @@ -57,13 +57,13 @@ namespace MonoDevelop.Projects.Formats.MSBuild public MSBuildResult Run ( ProjectConfigurationInfo[] configurations, ILogWriter logWriter, MSBuildVerbosity verbosity, - string[] runTargets, string[] evaluateItems, string[] evaluateProperties) + string[] runTargets, string[] evaluateItems, string[] evaluateProperties, int taskId) {
if (runTargets == null || runTargets.Length == 0)
throw new ArgumentException ("runTargets is empty");
MSBuildResult result = null; - BuildEngine.RunSTA (delegate { + BuildEngine.RunSTA (taskId, delegate { try {
var project = SetupProject (configurations);
currentLogWriter = logWriter;
|