Content-Length: 284485 | pFad | http://github.com/dotnet/tye/pull/1290/files/0d6d80acfb6f0adfc2f5a3eaec9a54a4eac50a69

5F Synchronize output buffers by philliphoff · Pull Request #1290 · dotnet/tye · GitHub
Skip to content
This repository has been archived by the owner on Nov 20, 2023. It is now read-only.

Synchronize output buffers #1290

Merged
merged 1 commit into from
Feb 3, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 38 additions & 11 deletions src/Microsoft.Tye.Core/ProcessUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ public static async Task<ProcessResult> RunAsync(
}
}

var outputLock = new SpinLock();

void WithOutputLock(Action action)
{
bool gotLock = false;

try
{
outputLock.Enter(ref gotLock);

action();
}
finally
{
if (gotLock)
{
outputLock.Exit();
}
}
}

var outputBuilder = new StringBuilder();
process.OutputDataReceived += (_, e) =>
{
Expand All @@ -90,7 +111,7 @@ public static async Task<ProcessResult> RunAsync(
}
else
{
outputBuilder.AppendLine(e.Data);
WithOutputLock(() => outputBuilder.AppendLine(e.Data));
}
};

Expand All @@ -108,7 +129,7 @@ public static async Task<ProcessResult> RunAsync(
}
else
{
errorBuilder.AppendLine(e.Data);
WithOutputLock(() => errorBuilder.AppendLine(e.Data));
}
};

Expand All @@ -129,15 +150,21 @@ public static async Task<ProcessResult> RunAsync(
process.WaitForExit(ProcessExitTimeoutMs);
ravipal marked this conversation as resolved.
Show resolved Hide resolved
}

if (throwOnError && process.ExitCode != 0)
{
processLifetimeTask.TrySetException(new InvalidOperationException($"Command {filename} {arguments} returned exit code {process.ExitCode}. Standard error: \"{errorBuilder.ToString()}\""));
}
else
{
// Since the process has exited, no additional data will be written to either output buffer or error buffer, it's thread-safe to call ToString() on both outputBuilder and errorBuilder.
processLifetimeTask.TrySetResult(new ProcessResult(outputBuilder.ToString(), errorBuilder.ToString(), process.ExitCode));
}
// NOTE: If WaitForExit() returns false, more output may be written,
// so we must synchronize access to the output StringBuilders.

WithOutputLock(
() =>
{
if (throwOnError && process.ExitCode != 0)
{
processLifetimeTask.TrySetException(new InvalidOperationException($"Command {filename} {arguments} returned exit code {process.ExitCode}. Standard error: \"{errorBuilder.ToString()}\""));
}
else
{
processLifetimeTask.TrySetResult(new ProcessResult(outputBuilder.ToString(), errorBuilder.ToString(), process.ExitCode));
}
});
};

// lock ensures we're reading output when WaitForExit is called in process.Exited event.
Expand Down








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/dotnet/tye/pull/1290/files/0d6d80acfb6f0adfc2f5a3eaec9a54a4eac50a69

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy