Sharing a Mutex Across Multiple ASP .NET Applications

Juldhais Hengkyawan
3 min readMar 16, 2024

Recently, I was tasked with solving a privacy issue while converting a legacy document format to PDF.

The problem was quite serious: when multiple users accessed the conversion service simultaneously, sometimes their files were swapped.

Imagine the surprise (and the privacy nightmare) when Tom received Jerry’s file and vice versa.

This issue happened because we had two ASP.NET applications running on the same machine, both sharing the same converter application.

Management wanted a quick solution to this privacy issue.

After some thought, I decided that a Mutex would be the most efficient way to solve this problem.

The idea was simple: ensure that the document conversion process could only be accessed by one application at a time, even if multiple applications try to access it simultaneously.

This approach will eliminate the file swap issue and ensure user data remains private.

The Mutex

Mutex is a synchronization mechanism that ensures only one thread or process can enter a specific code section at a time.

However, since two ASP .NET applications are accessing the same resource, we need to configure Mutex to allow sharing between those two applications.

Two things must be configured: the Mutex access rule and the Mutex name. These will allow the Mutex to be securely shared between two different applications.

Mutex Access Rule

The key here is the usage of WellKnownSidType.BuiltinUsersSid. This will enable the Mutex to be securely shared between both applications, which are run by the same IIS user account.

var accessRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
MutexRights.FullControl,
AccessControlType.Allow);

var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(accessRule);

We can also widen the scope by using WellKnownSidType.WorldSid. However, it will be less secure since the Mutex will become accessible to anyone on the machine.

Mutex Name

To share the same Mutex between applications, we must ensure that the Mutex name is set correctly.

using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))
{
// ...
}

The Mutex name has to be the same between applications, and it must have a “Global\” prefix to ensure it is visible across all sessions on the machine.

Mutex Implementation

After configuring the access rule and name, we proceeded to create the Mutex implementation:

var accessRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
MutexRights.FullControl,
AccessControlType.Allow);

var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(accessRule);

using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))
{
try
{
// Attempt to acquire the mutex
// Waiting up to 2 minutes for availability
mutex.WaitOne(120000);

// If acquired, run the document conversion process
return RunConversion(doc);
}
catch (AbandonedMutexException)
{
// If the mutex was abandoned, release it and try to acquire it again
mutex.ReleaseMutex();

// Wait again up to 2 minutes for the mutex
mutex.WaitOne(120000);

// Once acquired, re-run the document conversion process
return RunConversion(doc);
}
finally
{
// Always release the mutex when done to allow other processes to use the resource
mutex.ReleaseMutex();
}
}

Testing

I ran multiple simultaneous requests to test the application using the PowerShell command:

Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/1 -OutFile C:\file1.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/2 -OutFile C:\file2.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/3 -OutFile C:\file3.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/4 -OutFile C:\file4.pdf}
...etc

After conducting tests and regressions, the hotfix was deployed to production. The complex privacy issue was solved with a relatively simple solution.

Thank you for reading 👍

--

--