Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Henry <ludovic@xamarin.com>2015-10-13 21:24:05 +0300
committerLudovic Henry <ludovic@xamarin.com>2015-10-14 03:35:59 +0300
commite5fbaa4190ecffa910872a87ec874f1275e6431a (patch)
tree1fffa59320277e2a7e5f83d8d0d32a9af5520755 /mcs/class/System/System.Diagnostics
parentf7d03df3bf7650b7eb23401e52fd4f91803e0f0f (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.cs22
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