Add global lock on startup to prevent race conditions

This commit is contained in:
Kamil Trzciński 2022-11-15 17:00:13 +01:00
parent 40be8eee70
commit 6211bc4f42
10 changed files with 109 additions and 58 deletions

View file

@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.1" />
<PackageReference Include="TaskScheduler" Version="2.10.1" />
</ItemGroup>

85
CommonHelpers/Instance.cs Normal file
View file

@ -0,0 +1,85 @@
using System;
using System.IO;
using System.Linq;
using System.Security;
using System.Security.Principal;
using System.Security.AccessControl;
using System.Windows.Forms;
namespace CommonHelpers
{
public static class Instance
{
public static LibreHardwareMonitor.Hardware.Computer HardwareComputer = new LibreHardwareMonitor.Hardware.Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
IsStorageEnabled = true,
IsBatteryEnabled = true
};
private static Mutex? runOnceMutex;
private const String GLOBAL_MUTEX_NAME = "Global\\SteamDeckToolsCommonHelpers";
private const int GLOBAL_DEFAULT_TIMEOUT = 5000;
public static void Open(String title, String? runOnce = null, int runOnceTimeout = 100)
{
if (runOnce is not null)
{
RunOnce(title, runOnce, runOnceTimeout);
}
using (var globalLock = TryCreateOrOpenExistingMutex(GLOBAL_MUTEX_NAME))
{
if (!globalLock.WaitOne(GLOBAL_DEFAULT_TIMEOUT))
{
Fatal(title, "Failed to acquire global mutex.");
}
if (!Vlv0100.IsSupported())
{
String message = "";
message += "Current device is not supported.\n";
message += "FirmwareVersion: " + Vlv0100.GetFirmwareVersion().ToString("X") + "\n";
message += "BoardID: " + Vlv0100.GetBoardID().ToString("X") + "\n";
message += "PDCS: " + Vlv0100.GetPDCS().ToString("X") + "\n";
Fatal(title, message);
}
HardwareComputer.Open();
globalLock.ReleaseMutex();
}
}
public static void RunOnce(String title, String mutexName, int runOnceTimeout = 1000)
{
runOnceMutex = TryCreateOrOpenExistingMutex(mutexName);
if (!runOnceMutex.WaitOne(runOnceTimeout))
{
Fatal(title, "Run many times");
}
}
public static void Fatal(String title, String message)
{
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(1);
}
private static Mutex TryCreateOrOpenExistingMutex(string name)
{
MutexSecurity mutexSecurity = new();
SecurityIdentifier identity = new(WellKnownSidType.WorldSid, null);
mutexSecurity.AddAccessRule(new MutexAccessRule(identity, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));
var mutex = new Mutex(false, name, out _);
mutex.SetAccessControl(mutexSecurity);
return mutex;
}
}
}

View file

@ -9,11 +9,11 @@
<StartupObject>FanControl.Program</StartupObject>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Version>0.1.0</Version>
<ApplicationIcon>FanControl.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.1" />
<PackageReference Include="TaskScheduler" Version="2.10.1" />
<Content Include="FanControl.ico" />
</ItemGroup>
<ItemGroup>

View file

@ -69,7 +69,7 @@
this.notifyIcon.ContextMenuStrip = this.contextMenu;
this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon")));
this.notifyIcon.Text = "Steam Deck Fan Control";
this.notifyIcon.Visible = true;
this.notifyIcon.Visible = false;
this.notifyIcon.DoubleClick += new System.EventHandler(this.formShow_Event);
//
// contextMenu

View file

@ -1,4 +1,5 @@
using CommonHelpers.FromLibreHardwareMonitor;
using CommonHelpers;
using CommonHelpers.FromLibreHardwareMonitor;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -27,7 +28,10 @@ namespace FanControl
InitializeComponent();
Text += " v" + Application.ProductVersion.ToString();
Instance.Open(Text, "Global\\FanControlOnce");
notifyIcon.Text = Text;
notifyIcon.Visible = true;
toolStripMenuItemAlwaysOnTop.Checked = TopMost = Properties.Settings.Default.AlwaysOnTop;
toolStripMenuItemStartupOnBoot.Visible = startupManager.IsAvailable;

View file

@ -39,17 +39,8 @@ namespace FanControl
[CategoryAttribute("Board")]
public String PDVersion { get; private set; } = Vlv0100.GetFirmwareVersion().ToString("X");
private LibreHardwareMonitor.Hardware.Computer libreHardwareComputer = new LibreHardwareMonitor.Hardware.Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
IsStorageEnabled = true,
IsBatteryEnabled = true
};
public FanController()
{
libreHardwareComputer.Open();
}
private void visitHardware(IHardware hardware)
@ -92,7 +83,7 @@ namespace FanControl
foreach (var sensor in allSensors.Values)
sensor.Reset();
foreach (var hardware in libreHardwareComputer.Hardware)
foreach (var hardware in Instance.HardwareComputer.Hardware)
visitHardware(hardware);
allSensors["Batt"].Update("VLV0100", Vlv0100.GetBattTemperature(), Mode);
@ -131,7 +122,6 @@ namespace FanControl
public void Dispose()
{
libreHardwareComputer.Close();
}
}
}

View file

@ -11,20 +11,7 @@ namespace FanControl
internal class Program
{
static void Main(string[] args)
{
if (!Vlv0100.IsSupported())
{
String message = "";
message += "Current device is not supported.\n";
message += "FirmwareVersion: " + Vlv0100.GetFirmwareVersion().ToString("X") + "\n";
message += "BoardID: " + Vlv0100.GetBoardID().ToString("X") + "\n";
message += "PDCS: " + Vlv0100.GetPDCS().ToString("X") + "\n";
String title = "Steam Deck Fan Control v" + Application.ProductVersion.ToString();
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
{
Application.Run(new FanControlForm());
}
}

View file

@ -1,4 +1,5 @@
using CommonHelpers.FromLibreHardwareMonitor;
using CommonHelpers;
using CommonHelpers.FromLibreHardwareMonitor;
using Microsoft.VisualBasic.Logging;
using PerformanceOverlay.External;
using RTSSSharedMemoryNET;
@ -9,13 +10,15 @@ using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
namespace PerformanceOverlay
{
internal class Controller : IDisposable
{
public const String Title = "Performance Overlay";
public readonly String TitleWithVersion = Title + " v" + Application.ProductVersion.ToString();
public readonly String TitleWithVersion = Title + " v" + System.Windows.Forms.Application.ProductVersion.ToString();
Container components = new Container();
RTSSSharedMemoryNET.OSD? osd;
@ -28,18 +31,12 @@ namespace PerformanceOverlay
"Starts Performance Overlay on Windows startup."
);
LibreHardwareMonitor.Hardware.Computer libreHardwareComputer = new LibreHardwareMonitor.Hardware.Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
IsStorageEnabled = true,
IsBatteryEnabled = true
};
public Controller()
{
var contextMenu = new System.Windows.Forms.ContextMenuStrip(components);
Instance.Open(TitleWithVersion, "Global\\PerformanceOverlay");
showItem = new ToolStripMenuItem("&Show OSD");
showItem.Click += ShowItem_Click;
showItem.Checked = Settings.Default.ShowOSD;
@ -222,7 +219,7 @@ namespace PerformanceOverlay
private void ExitItem_Click(object? sender, EventArgs e)
{
Application.Exit();
System.Windows.Forms.Application.Exit();
}
public void Dispose()

View file

@ -8,6 +8,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Navigation;
using static PerformanceOverlay.Sensors;
using CommonHelpers;
namespace PerformanceOverlay
{
@ -288,33 +289,21 @@ namespace PerformanceOverlay
}
}
};
private LibreHardwareMonitor.Hardware.Computer libreHardwareComputer = new LibreHardwareMonitor.Hardware.Computer
{
IsCpuEnabled = true,
IsMemoryEnabled = true,
IsGpuEnabled = true,
IsStorageEnabled = true,
IsBatteryEnabled = true
};
public IList<ISensor> AllHardwareSensors { get; private set; } = new List<ISensor>();
public Sensors()
{
libreHardwareComputer.Open();
}
public void Dispose()
{
libreHardwareComputer.Close();
}
public void Update()
{
var allSensors = new List<ISensor>();
foreach (IHardware hardware in libreHardwareComputer.Hardware)
foreach (IHardware hardware in Instance.HardwareComputer.Hardware)
{
try
{

View file

@ -5,6 +5,8 @@ if [[ $# -ne 0 ]] && [[ $# -ne 1 ]]; then
exit 1
fi
set -eo pipefail
majorVer=$(cat VERSION)
lastVer=$(git tag --sort version:refname --list "$majorVer.*" | tail -n1)
if [[ -n "$lastVer" ]]; then
@ -19,8 +21,4 @@ fi
echo "MajorVer=$majorVer LastVer=$lastVer NextVer=$nextVer"
args="--configuration Release /property:Version=$nextVer"
if [[ -n "$1" ]]; then
dotnet build $args --output "$1"
else
dotnet build $args
fi
dotnet build $args --output "${1:-build-release/}"