Skip to content

Commit 7569565

Browse files
committed
Fix named mutex workaround for .NET Mono runtime
* Enable named mutex workaround when running on .NET using Mono runtime * Re-implement file locking logic to ensure intra- and inter-process mutual exclusion, and no longer leak lock files * Use mutex abstraction throughout test suite * Fix async race in ServerFailsWithLongTempPathUnix test case * Fixes #57002
1 parent d1a39e2 commit 7569565

File tree

6 files changed

+158
-104
lines changed

6 files changed

+158
-104
lines changed

src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,24 @@ public static bool IsRunningOnMono
3131
}
3232
}
3333
}
34+
/// <summary>
35+
/// Are we running on .NET 5 or later using the Mono runtime?
36+
/// Will also return true when running on Mono itself; if necessary
37+
/// we can use IsRunningOnMono to distinguish.
38+
/// </summary>
39+
public static bool IsUsingMonoRuntime
40+
{
41+
get
42+
{
43+
try
44+
{
45+
return !(Type.GetType("Mono.RuntimeStructs", throwOnError: false) is null);
46+
}
47+
catch
48+
{
49+
return false;
50+
}
51+
}
52+
}
3453
}
3554
}

src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void ConnectToServerFails()
7979
// to connect. When it fails it should fall back to in-proc
8080
// compilation.
8181
bool holdsMutex;
82-
using (var serverMutex = new Mutex(initiallyOwned: true,
82+
using (var serverMutex = BuildServerConnection.OpenOrCreateMutex(
8383
name: BuildServerConnection.GetServerMutexName(_pipeName),
8484
createdNew: out holdsMutex))
8585
{

src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public void MutexStopsServerStarting()
103103
var mutexName = BuildServerConnection.GetServerMutexName(pipeName);
104104

105105
bool holdsMutex;
106-
using (var mutex = new Mutex(initiallyOwned: true,
106+
using (var mutex = BuildServerConnection.OpenOrCreateMutex(
107107
name: mutexName,
108108
createdNew: out holdsMutex))
109109
{
@@ -119,7 +119,7 @@ public void MutexStopsServerStarting()
119119
}
120120
finally
121121
{
122-
mutex.ReleaseMutex();
122+
mutex.Dispose();
123123
}
124124
}
125125
}

src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ public async Task ServerFailsWithLongTempPathUnix()
304304
var newTempDir = _tempDirectory.CreateDirectory(new string('a', 100 - _tempDirectory.Path.Length));
305305
await ApplyEnvironmentVariables(
306306
new[] { new KeyValuePair<string, string>("TMPDIR", newTempDir.Path) },
307-
async () =>
307+
async () => await Task.Run(async () =>
308308
{
309309
using var serverData = await ServerUtil.CreateServer(_logger);
310310
var result = RunCommandLineCompiler(
@@ -317,7 +317,7 @@ await ApplyEnvironmentVariables(
317317

318318
var listener = await serverData.Complete();
319319
Assert.Equal(CompletionData.RequestCompleted, listener.CompletionDataList.Single());
320-
});
320+
}));
321321
}
322322

323323
[Fact]

src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public async Task NoServerConnection()
101101

102102
var thread = new Thread(() =>
103103
{
104-
using (var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created))
104+
using (var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created))
105105
using (var stream = NamedPipeUtil.CreateServer(pipeName))
106106
{
107107
readyMre.Set();
@@ -112,7 +112,7 @@ public async Task NoServerConnection()
112112
stream.Close();
113113

114114
doneMre.WaitOne();
115-
mutex.ReleaseMutex();
115+
mutex.Dispose();
116116
}
117117
});
118118

@@ -153,15 +153,14 @@ public async Task ServerShutdownsDuringProcessing()
153153
{
154154
using (var stream = NamedPipeUtil.CreateServer(pipeName))
155155
{
156-
var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created);
156+
var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created);
157157
readyMre.Set();
158158

159159
stream.WaitForConnection();
160160
connected = true;
161161

162162
// Client is waiting for a response. Close the mutex now. Then close the connection
163163
// so the client gets an error.
164-
mutex.ReleaseMutex();
165164
mutex.Dispose();
166165
stream.Close();
167166

0 commit comments

Comments
 (0)