diff options
author | Ludovic Henry <ludovic@xamarin.com> | 2015-10-13 21:24:05 +0300 |
---|---|---|
committer | Ludovic Henry <ludovic@xamarin.com> | 2015-10-14 03:35:59 +0300 |
commit | e5fbaa4190ecffa910872a87ec874f1275e6431a (patch) | |
tree | 1fffa59320277e2a7e5f83d8d0d32a9af5520755 /mcs/class/System/System.Diagnostics | |
parent | f7d03df3bf7650b7eb23401e52fd4f91803e0f0f (diff) |
[process] Wait for process completion before waiting for stdout/stderr
This fixes a race condition between the calls to Start and
BeginOutputReadLine/BeginErrorReadLine. This was triggered by the fact
that the call to WaitForExit (in StartBackgroundWaitForExit called by
Start_noshell) could be faster that the call to
BeginOutputReadLine/BeginErrorReadLine, leading to a null async_output,
which would make the WaitForExit call not wait for the output to finish.
This could make the call to Exited happen before a call to
OutputDataReceived/ErrorDataReceived.
To trigger this issue more reliably, you can simply add a sleep at the
beginning of AddInput in ProcessAsyncReader.
Diffstat (limited to 'mcs/class/System/System.Diagnostics')
-rw-r--r-- | mcs/class/System/System.Diagnostics/Process.cs | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/mcs/class/System/System.Diagnostics/Process.cs b/mcs/class/System/System.Diagnostics/Process.cs index 604b6a86e7d..d9888b7e403 100644 --- a/mcs/class/System/System.Diagnostics/Process.cs +++ b/mcs/class/System/System.Diagnostics/Process.cs @@ -1220,18 +1220,25 @@ namespace System.Diagnostics { if (process_handle == IntPtr.Zero) throw new InvalidOperationException ("No process is associated with this object."); - DateTime start = DateTime.UtcNow; + + if (!WaitForExit_internal (process_handle, ms)) + return false; + + if (ms >= 0) { + ms -= (int) (DateTime.UtcNow - start).TotalMilliseconds; + if (ms <= 0) + return false; + } + if (async_output != null && !async_output.IsCompleted) { if (false == async_output.AsyncWaitHandle.WaitOne (ms, false)) return false; // Timed out if (ms >= 0) { - DateTime now = DateTime.UtcNow; - ms -= (int) (now - start).TotalMilliseconds; + ms -= (int) (DateTime.UtcNow - start).TotalMilliseconds; if (ms <= 0) return false; - start = now; } } @@ -1246,12 +1253,9 @@ namespace System.Diagnostics { } } - bool exited = WaitForExit_internal (process_handle, ms); + OnExited (); - if (exited) - OnExited (); - - return exited; + return true; } /* Waits up to ms milliseconds for process 'handle' to |