Skip to content

Commit 20c9f56

Browse files
authored
Merge pull request #885 from martindevans/safer_vulkan_sysinfo
Safer Vulkan System Info
2 parents 955404f + 7fa8083 commit 20c9f56

File tree

2 files changed

+77
-23
lines changed

2 files changed

+77
-23
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System.Diagnostics;
2+
using System.Text;
3+
using System;
4+
5+
namespace LLama.Extensions;
6+
7+
internal static class ProcessExtensions
8+
{
9+
public static void SafeKill(this Process process, bool entireProcessTree = true)
10+
{
11+
if (process.HasExited)
12+
return;
13+
14+
// There's a race here! If the process closed between the above check
15+
// and the below `Kill` call then an `InvalidOperationException` will
16+
// be thrown! Catch it and move on.
17+
18+
try
19+
{
20+
#if NET5_0_OR_GREATER
21+
process.Kill(entireProcessTree);
22+
#else
23+
process.Kill();
24+
#endif
25+
process.WaitForExit(55);
26+
}
27+
catch (InvalidOperationException)
28+
{
29+
}
30+
}
31+
32+
/// <summary>
33+
/// Run a process for a certain amount of time and then terminate it
34+
/// </summary>
35+
/// <param name="process"></param>
36+
/// <param name="timeout"></param>
37+
/// <returns>return code, standard output, standard error, flag indicating if process exited or was terminated</returns>
38+
public static (int ret, string stdOut, string stdErr, bool ok) SafeRun(this Process process, TimeSpan timeout)
39+
{
40+
var stdOut = new StringBuilder();
41+
process.OutputDataReceived += (s, e) =>
42+
{
43+
stdOut.Append(e.Data);
44+
};
45+
46+
var stdErr = new StringBuilder();
47+
process.ErrorDataReceived += (s, e) =>
48+
{
49+
stdErr.Append(e.Data);
50+
};
51+
52+
process.Start();
53+
process.BeginOutputReadLine();
54+
process.BeginErrorReadLine();
55+
56+
var ok = process.WaitForExit((int)timeout.TotalMilliseconds);
57+
process.SafeKill();
58+
59+
return (process.ExitCode, stdOut.ToString(), stdErr.ToString(), ok);
60+
}
61+
}

LLama/Native/Load/SystemInfo.cs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace LLama.Native
1212
/// <param name="OSPlatform"></param>
1313
/// <param name="CudaMajorVersion"></param>
1414
/// <param name="VulkanVersion"></param>
15-
public record class SystemInfo(OSPlatform OSPlatform, int CudaMajorVersion, string? VulkanVersion)
15+
public record SystemInfo(OSPlatform OSPlatform, int CudaMajorVersion, string? VulkanVersion)
1616
{
1717
/// <summary>
1818
/// Get the system information of the current machine.
@@ -71,36 +71,29 @@ public static SystemInfo Get()
7171
// Note: on Linux, this requires `vulkan-tools` to be installed. (`sudo apt install vulkan-tools`)
7272
try
7373
{
74-
// Set up the process start info
75-
ProcessStartInfo start = new()
76-
{
77-
FileName = "vulkaninfo",
78-
Arguments = "--summary",
79-
RedirectStandardOutput = true,
80-
UseShellExecute = false,
81-
CreateNoWindow = true
82-
};
83-
84-
// Start the process
74+
// Start a process to read vulkan info
8575
Process process = new()
8676
{
87-
StartInfo = start
77+
StartInfo = new()
78+
{
79+
FileName = "vulkaninfo",
80+
Arguments = "--summary",
81+
RedirectStandardOutput = true,
82+
RedirectStandardError = true,
83+
UseShellExecute = false,
84+
CreateNoWindow = true
85+
}
8886
};
89-
process.Start();
90-
91-
// Read the output to a string
92-
string output = process.StandardOutput.ReadToEnd();
93-
94-
// Wait for the process to exit
95-
process.WaitForExit();
87+
var (exitCode, output, error, ok) = process.SafeRun(TimeSpan.FromSeconds(1));
88+
89+
if (!ok)
90+
return null;
9691

9792
// Return the output
9893
return output;
9994
}
100-
catch (Exception e)
95+
catch
10196
{
102-
//Console.WriteLine(e);
103-
10497
// Return null if we failed to get the Vulkan version
10598
return null;
10699
}

0 commit comments

Comments
 (0)