From 6f73154e013c8eef343fd1b505f9f5152cf23856 Mon Sep 17 00:00:00 2001 From: Srdjan Zivojinovic Date: Mon, 2 Mar 2026 10:26:59 +0100 Subject: [PATCH] #8 fix: resolve JavaService deadlock when reading process streams --- src/Server/Services/JavaService.cs | 10 ++++++++-- src/Server/Services/MustangCliService.cs | 14 ++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Server/Services/JavaService.cs b/src/Server/Services/JavaService.cs index 69adaed..dde87f6 100644 --- a/src/Server/Services/JavaService.cs +++ b/src/Server/Services/JavaService.cs @@ -38,11 +38,17 @@ public async Task GetJavaInfoAsync(CancellationToken cancellatio return new JavaInfoResult(IsAvailable: false, properties); } - string stdout = await process.StandardOutput.ReadToEndAsync(cancellationToken); - string stderr = await process.StandardError.ReadToEndAsync(cancellationToken); + // Read both streams concurrently to avoid deadlock + Task stdoutTask = process.StandardOutput.ReadToEndAsync(cancellationToken); + Task stderrTask = process.StandardError.ReadToEndAsync(cancellationToken); try { + // Wait for both reads to complete + await Task.WhenAll(stdoutTask, stderrTask); + string stdout = await stdoutTask; + string stderr = await stderrTask; + await process.WaitForExitAsync(cancellationToken); string allOutput = stdout + Environment.NewLine + stderr; diff --git a/src/Server/Services/MustangCliService.cs b/src/Server/Services/MustangCliService.cs index de1328f..8bfd608 100644 --- a/src/Server/Services/MustangCliService.cs +++ b/src/Server/Services/MustangCliService.cs @@ -107,11 +107,17 @@ private async Task ExecuteAsync(string action, string[] additi return MustangCliResult.Failed($"Failed to start Java process with Mustang CLI (action: {action})."); } - string stdout = await process.StandardOutput.ReadToEndAsync(cancellationToken); - string stderr = await process.StandardError.ReadToEndAsync(cancellationToken); + // Read both streams concurrently to avoid deadlock + Task stdoutTask = process.StandardOutput.ReadToEndAsync(cancellationToken); + Task stderrTask = process.StandardError.ReadToEndAsync(cancellationToken); try { + // Wait for both reads to complete + await Task.WhenAll(stdoutTask, stderrTask); + string stdout = await stdoutTask; + string stderr = await stderrTask; + await process.WaitForExitAsync(cancellationToken); return new MustangCliResult @@ -130,8 +136,8 @@ private async Task ExecuteAsync(string action, string[] additi return new MustangCliResult { ExitCode = (int)ErrorCode.ProcessingTimeout, - StandardOutput = stdout, - StandardError = stderr + StandardOutput = string.Empty, + StandardError = string.Empty }; } }