From 6211bc4f4271a310f9219444e6037db0c04de801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Tue, 15 Nov 2022 17:00:13 +0100 Subject: [PATCH] Add global lock on startup to prevent race conditions --- CommonHelpers/CommonHelpers.csproj | 1 + CommonHelpers/Instance.cs | 85 +++++++++++++++++++++++++++ FanControl/FanControl.csproj | 4 +- FanControl/FanControlForm.Designer.cs | 2 +- FanControl/FanControlForm.cs | 6 +- FanControl/FanController.cs | 12 +--- FanControl/Program.cs | 15 +---- PerformanceOverlay/Controller.cs | 19 +++--- PerformanceOverlay/Sensors.cs | 15 +---- build.sh | 8 +-- 10 files changed, 109 insertions(+), 58 deletions(-) create mode 100644 CommonHelpers/Instance.cs diff --git a/CommonHelpers/CommonHelpers.csproj b/CommonHelpers/CommonHelpers.csproj index e3c69ee..19b440a 100644 --- a/CommonHelpers/CommonHelpers.csproj +++ b/CommonHelpers/CommonHelpers.csproj @@ -8,6 +8,7 @@ + diff --git a/CommonHelpers/Instance.cs b/CommonHelpers/Instance.cs new file mode 100644 index 0000000..74f6f93 --- /dev/null +++ b/CommonHelpers/Instance.cs @@ -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; + } + } +} diff --git a/FanControl/FanControl.csproj b/FanControl/FanControl.csproj index 6c464a9..0784371 100644 --- a/FanControl/FanControl.csproj +++ b/FanControl/FanControl.csproj @@ -9,11 +9,11 @@ FanControl.Program app.manifest 0.1.0 + FanControl.ico - - + diff --git a/FanControl/FanControlForm.Designer.cs b/FanControl/FanControlForm.Designer.cs index cfc8c8d..38886eb 100644 --- a/FanControl/FanControlForm.Designer.cs +++ b/FanControl/FanControlForm.Designer.cs @@ -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 diff --git a/FanControl/FanControlForm.cs b/FanControl/FanControlForm.cs index 7bc0d3d..00b0ca2 100644 --- a/FanControl/FanControlForm.cs +++ b/FanControl/FanControlForm.cs @@ -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; diff --git a/FanControl/FanController.cs b/FanControl/FanController.cs index de541ab..b2d6b63 100644 --- a/FanControl/FanController.cs +++ b/FanControl/FanController.cs @@ -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(); } } } diff --git a/FanControl/Program.cs b/FanControl/Program.cs index aa153d2..fa9b28a 100644 --- a/FanControl/Program.cs +++ b/FanControl/Program.cs @@ -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()); } } diff --git a/PerformanceOverlay/Controller.cs b/PerformanceOverlay/Controller.cs index 64a68f8..085dd93 100644 --- a/PerformanceOverlay/Controller.cs +++ b/PerformanceOverlay/Controller.cs @@ -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() diff --git a/PerformanceOverlay/Sensors.cs b/PerformanceOverlay/Sensors.cs index a5a0faa..2e961bc 100644 --- a/PerformanceOverlay/Sensors.cs +++ b/PerformanceOverlay/Sensors.cs @@ -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 AllHardwareSensors { get; private set; } = new List(); public Sensors() { - libreHardwareComputer.Open(); } public void Dispose() { - libreHardwareComputer.Close(); } public void Update() { var allSensors = new List(); - foreach (IHardware hardware in libreHardwareComputer.Hardware) + foreach (IHardware hardware in Instance.HardwareComputer.Hardware) { try { diff --git a/build.sh b/build.sh index 7148fe2..670d702 100644 --- a/build.sh +++ b/build.sh @@ -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/}"