diff options
author | Rodrigo Kumpera <kumpera@gmail.com> | 2015-10-06 17:40:47 +0300 |
---|---|---|
committer | Rodrigo Kumpera <kumpera@gmail.com> | 2015-10-06 17:40:47 +0300 |
commit | 7aae649458bceb4375b74f078c4f24ddd4a486f5 (patch) | |
tree | 74511d0e06ad5d091cbfdd0c446748b97768e081 /mcs/class/System/System.Diagnostics | |
parent | e6ad2dc73b415e091c80a9912c66e86af1e7a761 (diff) | |
parent | e5e97eafef17cca8d9053f69914a4c171f469605 (diff) |
Merge pull request #2060 from ludovic-henry/socket-rework-async
[socket] Complete refactor of Begin/End and Async
Diffstat (limited to 'mcs/class/System/System.Diagnostics')
-rw-r--r-- | mcs/class/System/System.Diagnostics/Process.cs | 140 |
1 files changed, 40 insertions, 100 deletions
diff --git a/mcs/class/System/System.Diagnostics/Process.cs b/mcs/class/System/System.Diagnostics/Process.cs index 44fc79725bc..5ab69b4f6d4 100644 --- a/mcs/class/System/System.Diagnostics/Process.cs +++ b/mcs/class/System/System.Diagnostics/Process.cs @@ -1260,7 +1260,7 @@ namespace System.Diagnostics { DateTime start = DateTime.UtcNow; if (async_output != null && !async_output.IsCompleted) { - if (false == async_output.WaitHandle.WaitOne (ms, false)) + if (false == async_output.AsyncWaitHandle.WaitOne (ms, false)) return false; // Timed out if (ms >= 0) { @@ -1273,7 +1273,7 @@ namespace System.Diagnostics { } if (async_error != null && !async_error.IsCompleted) { - if (false == async_error.WaitHandle.WaitOne (ms, false)) + if (false == async_error.AsyncWaitHandle.WaitOne (ms, false)) return false; // Timed out if (ms >= 0) { @@ -1346,70 +1346,44 @@ namespace System.Diagnostics { } [StructLayout (LayoutKind.Sequential)] - sealed class ProcessAsyncReader : IThreadPoolWorkItem + sealed class ProcessAsyncReader : IOAsyncResult { - /* - The following fields match those of SocketAsyncResult. - This is so that changes needed in the runtime to handle - asynchronous reads are trivial - Keep this in sync with SocketAsyncResult in - ./System.Net.Sockets/Socket.cs and MonoSocketAsyncResult - in metadata/socket-io.h. - */ - /* DON'T shuffle fields around. DON'T remove fields */ - public object Sock; - public IntPtr handle; - public object state; - public AsyncCallback callback; - public ManualResetEvent wait_handle; - - public Exception delayedException; - - public object EndPoint; - byte [] buffer = new byte [4196]; - public int Offset; - public int Size; - public int SockFlags; - - public object AcceptSocket; - public object[] Addresses; - public int port; - public object Buffers; // Reserve this slot in older profiles - public bool ReuseSocket; // Disconnect - public object acc_socket; - public int total; - public bool completed_sync; - bool completed; - bool err_out; // true -> stdout, false -> stderr - internal int error; - public int operation = 8; // MAGIC NUMBER: see Socket.cs:AsyncOperation - public AsyncResult async_result; - public int EndCalled; - // These fields are not in SocketAsyncResult Process process; + IntPtr handle; Stream stream; + bool err_out; + StringBuilder sb = new StringBuilder (); - public AsyncReadHandler ReadHandler; + byte[] buffer = new byte [4096]; public ProcessAsyncReader (Process process, IntPtr handle, bool err_out) + : base (null, null) { this.process = process; this.handle = handle; - stream = new FileStream (handle, FileAccess.Read, false); - this.ReadHandler = new AsyncReadHandler (AddInput); + this.stream = new FileStream (handle, FileAccess.Read, false); this.err_out = err_out; } - public void AddInput () + public void BeginRead () + { + IOSelector.Add (this.handle, new IOSelectorJob (IOOperation.Read, s => AddInput ((ProcessAsyncReader) s), this)); + } + + public void AddInput (ProcessAsyncReader reader) { lock (this) { int nread = stream.Read (buffer, 0, buffer.Length); if (nread == 0) { - completed = true; - if (wait_handle != null) - wait_handle.Set (); - FlushLast (); + IsCompleted = true; + + Flush (true); + if (err_out) + process.OnOutputDataReceived (null); + else + process.OnErrorDataReceived (null); + return; } @@ -1423,82 +1397,49 @@ namespace System.Diagnostics { } Flush (false); - ReadHandler.BeginInvoke (null, this); - } - } - void FlushLast () - { - Flush (true); - if (err_out) { - process.OnOutputDataReceived (null); - } else { - process.OnErrorDataReceived (null); + IOSelector.Add (this.handle, new IOSelectorJob (IOOperation.Read, s => AddInput ((ProcessAsyncReader) s), this)); } } - + void Flush (bool last) { - if (sb.Length == 0 || - (err_out && process.output_canceled) || - (!err_out && process.error_canceled)) + if (sb.Length == 0 || (err_out && process.output_canceled) || (!err_out && process.error_canceled)) return; - string total = sb.ToString (); + string[] strs = sb.ToString ().Split ('\n'); + sb.Length = 0; - string [] strs = total.Split ('\n'); - int len = strs.Length; - if (len == 0) + + if (strs.Length == 0) return; - for (int i = 0; i < len - 1; i++) { + for (int i = 0; i < strs.Length - 1; i++) { if (err_out) process.OnOutputDataReceived (strs [i]); else process.OnErrorDataReceived (strs [i]); } - string end = strs [len - 1]; - if (last || (len == 1 && end == "")) { - if (err_out) { + string end = strs [strs.Length - 1]; + if (last || (strs.Length == 1 && end == "")) { + if (err_out) process.OnOutputDataReceived (end); - } else { + else process.OnErrorDataReceived (end); - } } else { sb.Append (end); } } - public bool IsCompleted { - get { return completed; } - } - - public WaitHandle WaitHandle { - get { - lock (this) { - if (wait_handle == null) - wait_handle = new ManualResetEvent (completed); - return wait_handle; - } - } - } - public void Close () { - RemoveFromIOThreadPool (handle); + IOSelector.Remove (handle); stream.Close (); } - [MethodImplAttribute(MethodImplOptions.InternalCall)] - extern static void RemoveFromIOThreadPool (IntPtr handle); - - void IThreadPoolWorkItem.ExecuteWorkItem() - { - async_result.Invoke (); - } - - void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) + internal override void CompleteDisposed () { + throw new NotSupportedException (); } } @@ -1507,7 +1448,6 @@ namespace System.Diagnostics { bool error_canceled; ProcessAsyncReader async_output; ProcessAsyncReader async_error; - delegate void AsyncReadHandler (); [ComVisibleAttribute(false)] public void BeginOutputReadLine () @@ -1522,7 +1462,7 @@ namespace System.Diagnostics { output_canceled = false; if (async_output == null) { async_output = new ProcessAsyncReader (this, stdout_rd, true); - async_output.ReadHandler.BeginInvoke (null, async_output); + async_output.BeginRead (); } } @@ -1554,7 +1494,7 @@ namespace System.Diagnostics { error_canceled = false; if (async_error == null) { async_error = new ProcessAsyncReader (this, stderr_rd, false); - async_error.ReadHandler.BeginInvoke (null, async_error); + async_error.BeginRead (); } } |