Hold singleton mutex open if owned

Still not perfect, thanks to C#'s async threading weirdness it's possible for ownership of the mutex to still be lost - no idea how, but it should mostly work fine.
This commit is contained in:
pizzaboxer 2023-02-19 17:38:02 +00:00
parent 1e46aaa929
commit 222006fa6a
2 changed files with 31 additions and 8 deletions

View File

@ -20,7 +20,7 @@ using Bloxstrap.Models;
namespace Bloxstrap
{
public partial class Bootstrapper
public class Bootstrapper
{
#region Properties
@ -349,7 +349,7 @@ namespace Bloxstrap
// whether we should wait for roblox to exit to handle stuff in the background or clean up after roblox closes
bool shouldWait = false;
Mutex singletonMutex;
Mutex? singletonMutex = null;
if (App.Settings.Prop.MultiInstanceLaunching)
{
@ -357,15 +357,15 @@ namespace Bloxstrap
// this might be a bit problematic since this mutex will be released when the first launched instance is closed...
try
{
singletonMutex = Mutex.OpenExisting("ROBLOX_singletonMutex");
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Warning - singleton mutex already exists");
Mutex.OpenExisting("ROBLOX_singletonMutex");
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Warning - singleton mutex already exists!");
}
catch
{
singletonMutex = new Mutex(true, "ROBLOX_singletonMutex");
}
shouldWait = true;
}
}
Process gameClient = Process.Start(Path.Combine(_versionFolder, "RobloxPlayerBeta.exe"), _launchCommandLine);
List<Process> autocloseProcesses = new();
@ -454,6 +454,27 @@ namespace Bloxstrap
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Autoclosing process '{process.ProcessName}' (PID {process.Id})");
process.Kill();
}
if (singletonMutex is not null)
{
// we've got ownership of the roblox singleton mutex!
// if we stop running, everything will screw up once any more instances launched
// also this code is blehhhh im sure theres a better way of checking if the process count changed like this
int runningProcesses = -1;
while (runningProcesses != 0)
{
int runningProcessesNow = Utilities.GetProcessCount("RobloxPlayerBeta", false);
if (runningProcessesNow != runningProcesses)
{
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] We have singleton mutex ownership! Running in background until all Roblox processes are closed ({runningProcessesNow} remaining)...");
runningProcesses = runningProcessesNow;
}
await Task.Delay(5000);
}
}
}
public void CancelInstall()

View File

@ -26,12 +26,14 @@ namespace Bloxstrap.Helpers
return -1;
}
public static int GetProcessCount(string processName)
public static int GetProcessCount(string processName, bool log = true)
{
if (log)
App.Logger.WriteLine($"[Utilities::CheckIfProcessRunning] Checking if '{processName}' is running...");
Process[] processes = Process.GetProcessesByName("RobloxPlayerBeta");
if (log)
App.Logger.WriteLine($"[Utilities::CheckIfProcessRunning] Found {processes.Length} process(es) running for '{processName}'");
return processes.Length;