diff options
Diffstat (limited to 'main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution')
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DefaultExecutionHandler.cs | 2 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionHandler.cs | 2 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs | 3 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/MonoPlatformExecutionHandler.cs | 2 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/NativePlatformExecutionHandler.cs | 2 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessAsyncOperation.cs (renamed from main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IProcessAsyncOperation.cs) | 33 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessHostController.cs | 81 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs | 43 | ||||
-rw-r--r-- | main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessWrapper.cs | 103 |
9 files changed, 87 insertions, 184 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DefaultExecutionHandler.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DefaultExecutionHandler.cs index e56f71e714..7cac46b2a8 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DefaultExecutionHandler.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DefaultExecutionHandler.cs @@ -37,7 +37,7 @@ namespace MonoDevelop.Core.Execution return Runtime.ProcessService.GetDefaultExecutionHandler (command) != null; } - public IProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) + public ProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) { IExecutionHandler handler = Runtime.ProcessService.GetDefaultExecutionHandler (command); return handler.Execute (command, console); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionHandler.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionHandler.cs index da3985afa5..c4a2dd0790 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionHandler.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionHandler.cs @@ -35,7 +35,7 @@ namespace MonoDevelop.Core.Execution return command is DotNetExecutionCommand; } - public IProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) + public ProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) { DotNetExecutionCommand cmd = (DotNetExecutionCommand) command; if (cmd.TargetRuntime == null) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs index a0a1c7b6d0..fe12bceeb8 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; +using System.Threading; namespace MonoDevelop.Core.Execution { @@ -56,6 +57,6 @@ namespace MonoDevelop.Core.Execution /// <param name='console'> /// Console where to log the output /// </param> - IProcessAsyncOperation Execute (ExecutionCommand command, IConsole console); + ProcessAsyncOperation Execute (ExecutionCommand command, IConsole console); } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/MonoPlatformExecutionHandler.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/MonoPlatformExecutionHandler.cs index a164a13508..42451c68f2 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/MonoPlatformExecutionHandler.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/MonoPlatformExecutionHandler.cs @@ -44,7 +44,7 @@ namespace MonoDevelop.Core.Execution this.monoPath = monoPath; } - public override IProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) + public override ProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) { DotNetExecutionCommand dotcmd = (DotNetExecutionCommand) command; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/NativePlatformExecutionHandler.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/NativePlatformExecutionHandler.cs index 6783653e3a..8c429a80ae 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/NativePlatformExecutionHandler.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/NativePlatformExecutionHandler.cs @@ -45,7 +45,7 @@ namespace MonoDevelop.Core.Execution this.defaultEnvironmentVariables = defaultEnvironmentVariables; } - public virtual IProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) + public virtual ProcessAsyncOperation Execute (ExecutionCommand command, IConsole console) { ProcessExecutionCommand cmd = (ProcessExecutionCommand) command; IDictionary<string, string> vars; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IProcessAsyncOperation.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessAsyncOperation.cs index 977ea67c7c..1cdeadd47f 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IProcessAsyncOperation.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessAsyncOperation.cs @@ -29,25 +29,34 @@ using System; using MonoDevelop.Core; using MonoDevelop.Core.ProgressMonitoring; +using System.Threading.Tasks; +using System.Threading; namespace MonoDevelop.Core.Execution { - public interface IProcessAsyncOperation: IAsyncOperation, IDisposable + public class ProcessAsyncOperation: AsyncOperation { - int ExitCode { get; } + protected ProcessAsyncOperation () + { + } + + public ProcessAsyncOperation (Task task, CancellationTokenSource cancellationTokenSource): base (task, cancellationTokenSource) + { + } + + public int ExitCode { get; set; } - int ProcessId { get; } + public int ProcessId { get; set; } } - public class NullProcessAsyncOperation : NullAsyncOperation, IProcessAsyncOperation + public class NullProcessAsyncOperation : ProcessAsyncOperation { - public NullProcessAsyncOperation (bool success) : base (success, false) {} - public int ExitCode { get { return ((IAsyncOperation)this).Success? 0 : 1; } } - public int ProcessId { get { return 0; } } - - void IDisposable.Dispose () {} - - public new static NullProcessAsyncOperation Success = new NullProcessAsyncOperation (true); - public new static NullProcessAsyncOperation Failure = new NullProcessAsyncOperation (false); + public NullProcessAsyncOperation (int exitCode) + { + ExitCode = exitCode; + } + + public static NullProcessAsyncOperation Success = new NullProcessAsyncOperation (0); + public static NullProcessAsyncOperation Failure = new NullProcessAsyncOperation (1); } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessHostController.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessHostController.cs index 11be57b373..e22d48cba8 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessHostController.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessHostController.cs @@ -50,7 +50,7 @@ namespace MonoDevelop.Core.Execution DateTime lastReleaseTime; bool starting; bool stopping; - IProcessAsyncOperation process; + ProcessAsyncOperation process; Timer timer; string id; IExecutionHandler executionHandlerFactory; @@ -130,10 +130,10 @@ namespace MonoDevelop.Core.Execution cmd.UserAssemblyPaths = userAssemblyPaths; cmd.DebugMode = isDebugMode; ProcessHostConsole cons = new ProcessHostConsole (); - process = executionHandlerFactory.Execute (cmd, cons); + var p = process = executionHandlerFactory.Execute (cmd, cons); Counters.ExternalHostProcesses++; - process.Completed += ProcessExited; + process.Task.ContinueWith ((t) => ProcessExited (p)); } catch (Exception ex) { if (tmpFile != null) { @@ -155,7 +155,7 @@ namespace MonoDevelop.Core.Execution } } - void ProcessExited (IAsyncOperation oper) + void ProcessExited (ProcessAsyncOperation oper) { lock (this) { @@ -307,7 +307,7 @@ namespace MonoDevelop.Core.Execution void WaitTimeout (object sender, System.Timers.ElapsedEventArgs args) { try { - IProcessAsyncOperation oldProcess; + ProcessAsyncOperation oldProcess; lock (this) { if (references > 0) { @@ -395,75 +395,4 @@ namespace MonoDevelop.Core.Execution { } } - - class InernalProcessHost: Process, IProcessAsyncOperation - { - object doneLock = new object (); - bool finished; - OperationHandler completed; - - public InernalProcessHost () - { - Exited += delegate { - lock (doneLock) { - finished = true; - Monitor.PulseAll (doneLock); - if (completed != null) - completed (this); - } - }; - } - - public int ProcessId { - get { return Id; } - } - - public event OperationHandler Completed { - add { - lock (doneLock) { - completed += value; - if (finished) - value (this); - } - } - remove { - lock (doneLock) { - completed -= value; - } - } - } - - public void Cancel () - { - Kill (); - } - - public void WaitForCompleted () - { - lock (doneLock) { - while (!finished) - Monitor.Wait (doneLock); - } - } - - public bool IsCompleted { - get { - lock (doneLock) { - return finished; - } - } - } - - public bool Success { - get { - return true; - } - } - - public bool SuccessWithWarnings { - get { - return true; - } - } - } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs index b88803792d..94e679d891 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs @@ -155,15 +155,9 @@ namespace MonoDevelop.Core.Execution // p.Exited += exited; // p.EnableRaisingEvents = true; - if (exited != null) { - MonoDevelop.Core.OperationHandler handler = null; - handler = delegate (MonoDevelop.Core.IAsyncOperation op) { - op.Completed -= handler; - exited (p, EventArgs.Empty); - }; - ((MonoDevelop.Core.IAsyncOperation)p).Completed += handler; - } - + if (exited != null) + p.Task.ContinueWith (t => exited (p, EventArgs.Empty)); + Counters.ProcessesStarted++; p.Start (); return p; @@ -194,13 +188,13 @@ namespace MonoDevelop.Core.Execution return startInfo; } - public IProcessAsyncOperation StartConsoleProcess (string command, string arguments, string workingDirectory, IConsole console, + public ProcessAsyncOperation StartConsoleProcess (string command, string arguments, string workingDirectory, IConsole console, EventHandler exited) { return StartConsoleProcess (command, arguments, workingDirectory, null, console, exited); } - public IProcessAsyncOperation StartConsoleProcess (string command, string arguments, string workingDirectory, + public ProcessAsyncOperation StartConsoleProcess (string command, string arguments, string workingDirectory, IDictionary<string, string> environmentVariables, IConsole console, EventHandler exited) { if ((console == null || (console is ExternalConsole)) && externalConsoleHandler != null) { @@ -218,11 +212,8 @@ namespace MonoDevelop.Core.Execution console != null ? !console.CloseOnDispose : false); if (p != null) { - if (exited != null) { - p.Completed += delegate { - exited (p, EventArgs.Empty); - }; - } + if (exited != null) + p.Task.ContinueWith (t => exited (p, EventArgs.Empty)); Counters.ProcessesStarted++; return p; } else { @@ -234,8 +225,8 @@ namespace MonoDevelop.Core.Execution foreach (KeyValuePair<string, string> kvp in environmentVariables) psi.EnvironmentVariables [kvp.Key] = kvp.Value; ProcessWrapper pw = StartProcess (psi, console.Out, console.Error, null); - new ProcessMonitor (console, pw, exited); - return pw; + new ProcessMonitor (console, pw.ProcessAsyncOperation, exited); + return pw.ProcessAsyncOperation; } public IExecutionHandler GetDefaultExecutionHandler (ExecutionCommand command) @@ -420,22 +411,22 @@ namespace MonoDevelop.Core.Execution { public IConsole console; EventHandler exited; - IProcessAsyncOperation operation; + ProcessAsyncOperation operation; - public ProcessMonitor (IConsole console, IProcessAsyncOperation operation, EventHandler exited) + public ProcessMonitor (IConsole console, ProcessAsyncOperation operation, EventHandler exited) { this.exited = exited; this.operation = operation; this.console = console; - operation.Completed += new OperationHandler (OnOperationCompleted); - console.CancelRequested += new EventHandler (OnCancelRequest); + operation.Task.ContinueWith (t => OnOperationCompleted ()); + console.CancelRequested += OnCancelRequest; } - public void OnOperationCompleted (IAsyncOperation op) + public void OnOperationCompleted () { try { if (exited != null) - exited (op, null); + exited (operation, EventArgs.Empty); if (!Platform.IsWindows && Mono.Unix.Native.Syscall.WIFSIGNALED (operation.ExitCode)) console.Log.WriteLine (GettextCatalog.GetString ("The application was terminated by a signal: {0}"), Mono.Unix.Native.Syscall.WTERMSIG (operation.ExitCode)); @@ -451,7 +442,7 @@ namespace MonoDevelop.Core.Execution operation.Cancel (); //remove the cancel handler, it will be attached again when StartConsoleProcess is called - console.CancelRequested -= new EventHandler (OnCancelRequest); + console.CancelRequested -= OnCancelRequest; } } @@ -475,5 +466,5 @@ namespace MonoDevelop.Core.Execution } } - public delegate IProcessAsyncOperation ExternalConsoleHandler (string command, string arguments, string workingDirectory, IDictionary<string, string> environmentVariables, string title, bool pauseWhenFinished); + public delegate ProcessAsyncOperation ExternalConsoleHandler (string command, string arguments, string workingDirectory, IDictionary<string, string> environmentVariables, string title, bool pauseWhenFinished); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessWrapper.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessWrapper.cs index a5f121882e..2aa4f7d099 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessWrapper.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessWrapper.cs @@ -2,36 +2,47 @@ using System; using System.Threading; using System.Diagnostics; +using System.Threading.Tasks; namespace MonoDevelop.Core.Execution { public delegate void ProcessEventHandler(object sender, string message); [System.ComponentModel.DesignerCategory ("Code")] - public class ProcessWrapper : Process, IProcessAsyncOperation + public class ProcessWrapper : Process { - private Thread captureOutputThread; private Thread captureErrorThread; ManualResetEvent endEventOut = new ManualResetEvent (false); ManualResetEvent endEventErr = new ManualResetEvent (false); bool done; object lockObj = new object (); + Task task; + ProcessAsyncOperation operation; + IDisposable customCancelToken; public ProcessWrapper () { } - public bool CancelRequested { get; private set; }
- + public bool CancelRequested { get; private set; } + + public Task Task { + get { return task; } + } + + public ProcessAsyncOperation ProcessAsyncOperation { + get { return operation; } + } + public new void Start () { CheckDisposed (); base.Start (); - - captureOutputThread = new Thread (new ThreadStart(CaptureOutput)); - captureOutputThread.Name = "Process output reader"; - captureOutputThread.IsBackground = true; - captureOutputThread.Start (); - + + task = Task.Factory.StartNew (CaptureOutput, TaskCreationOptions.LongRunning); + var cs = new CancellationTokenSource (); + operation = new ProcessAsyncOperation (task, cs); + cs.Token.Register (Cancel); + if (ErrorStreamChanged != null) { captureErrorThread = new Thread (new ThreadStart(CaptureError)); captureErrorThread.Name = "Process error reader"; @@ -40,6 +51,12 @@ namespace MonoDevelop.Core.Execution } else { endEventErr.Set (); } + operation.ProcessId = Id; + } + + public void SetCancellationToken (CancellationToken cancelToken) + { + customCancelToken = cancelToken.Register (Cancel); } public void WaitForOutput (int milliseconds) @@ -56,6 +73,7 @@ namespace MonoDevelop.Core.Execution private void CaptureOutput () { + Thread.CurrentThread.Name = "Process output reader"; try { if (OutputStreamChanged != null) { char[] buffer = new char [1024]; @@ -74,6 +92,9 @@ namespace MonoDevelop.Core.Execution if (endEventErr != null) endEventErr.WaitOne (); + if (HasExited) + operation.ExitCode = ExitCode; + OnExited (this, EventArgs.Empty); lock (lockObj) { @@ -108,9 +129,9 @@ namespace MonoDevelop.Core.Execution return; if (!done) - ((IAsyncOperation)this).Cancel (); + Cancel (); - captureOutputThread = captureErrorThread = null; + captureErrorThread = null; endEventOut.Close (); endEventErr.Close (); endEventOut = endEventErr = null; @@ -132,15 +153,7 @@ namespace MonoDevelop.Core.Execution throw new ObjectDisposedException ("ProcessWrapper"); } - int IProcessAsyncOperation.ExitCode { - get { return ExitCode; } - } - - int IProcessAsyncOperation.ProcessId { - get { return Id; } - } - - void IAsyncOperation.Cancel () + public void Cancel () { try { if (!done) { @@ -156,13 +169,12 @@ namespace MonoDevelop.Core.Execution } } - void IAsyncOperation.WaitForCompleted () - { - WaitForOutput (); - } - void OnExited (object sender, EventArgs args) { + if (customCancelToken != null) { + customCancelToken.Dispose (); + customCancelToken = null; + } try { if (!HasExited) WaitForExit (); @@ -171,49 +183,10 @@ namespace MonoDevelop.Core.Execution } finally { lock (lockObj) { done = true; - try { - if (completedEvent != null) - completedEvent (this); - } catch { - // Ignore - } } } } - event OperationHandler IAsyncOperation.Completed { - add { - bool raiseNow = false; - lock (lockObj) { - if (done) - raiseNow = true; - else - completedEvent += value; - } - if (raiseNow) - value (this); - } - remove { - lock (lockObj) { - completedEvent -= value; - } - } - } - - bool IAsyncOperation.Success { - get { return done ? ExitCode == 0 : false; } - } - - bool IAsyncOperation.SuccessWithWarnings { - get { return false; } - } - - bool IAsyncOperation.IsCompleted { - get { return done; } - } - - event OperationHandler completedEvent; - public event ProcessEventHandler OutputStreamChanged; public event ProcessEventHandler ErrorStreamChanged; } |