Skip to content

Commit

Permalink
Fix multiple instances of a game being allowed to start concurrently
Browse files Browse the repository at this point in the history
Regressed with ppy#6442.

Was not visible in test coverage because as per the inline comment, this
is an exceptional case where two different processes bind.

I'm not sure how to add test coverage for this, but I have tested
manually on both windows and macOS.
  • Loading branch information
peppy committed Dec 11, 2024
1 parent f5900ab commit 333419d
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions osu.Framework/Platform/NamedPipeIpcProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class NamedPipeIpcProvider : IDisposable

private NamedPipeServerStream? pipe;

private Mutex? mutex;

/// <summary>
/// Create a new provider.
/// </summary>
Expand All @@ -57,7 +59,17 @@ public bool Bind()

try
{
pipe = new NamedPipeServerStream($"osu-framework-{pipeName}", PipeDirection.InOut);
string name = $"osu-framework-{pipeName}";

// Named pipes from different processes are allowed to coexist, but we don't want this for our purposes.
// Using a system global mutex allows ensuring that only one osu!framework project using the same pipe name
// will be able to bind.
mutex = new Mutex(false, $"Global\\{name}", out bool createdNew);

if (!createdNew)
return false;

pipe = new NamedPipeServerStream(name, PipeDirection.InOut, 1);

listenTask = listen(pipe);

Expand Down Expand Up @@ -110,7 +122,8 @@ private async Task listen(NamedPipeServerStream pipe)
{
try
{
pipe.Disconnect();
if (pipe.IsConnected)
pipe.Disconnect();
}
catch
{
Expand Down Expand Up @@ -202,6 +215,8 @@ public void Dispose()

cancellationSource.Cancel();

mutex?.Dispose();

if (listenTask != null)
{
try
Expand Down

0 comments on commit 333419d

Please sign in to comment.