private static Task <BuildResponse> RunServerCompilationCore( RequestLanguage language, List <string> arguments, BuildPaths buildPaths, string pipeName, string keepAlive, string libEnvVariable, Func <string, string, bool> tryCreateServerFunc, CancellationToken cancellationToken) { var clientDir = buildPaths.ClientDirectory; var clientMutexName = BuildProtocolConstants.GetClientMutexName(pipeName); bool holdsMutex; using (var clientMutex = new Mutex(initiallyOwned: true, name: clientMutexName, createdNew: out holdsMutex)) { try { if (!holdsMutex) { try { holdsMutex = clientMutex.WaitOne(TimeOutMsNewProcess); if (!holdsMutex) { return(Task.FromResult <BuildResponse>(null)); } } catch (AbandonedMutexException) { holdsMutex = true; } } // Check for an already running server var serverMutexName = BuildProtocolConstants.GetServerMutexName(pipeName); Mutex mutexIgnore; bool wasServerRunning = Mutex.TryOpenExisting(serverMutexName, out mutexIgnore); var timeout = wasServerRunning ? TimeOutMsExistingProcess : TimeOutMsNewProcess; NamedPipeClientStream pipe = null; if (wasServerRunning || tryCreateServerFunc(clientDir, pipeName)) { pipe = TryConnectToServer(pipeName, timeout, cancellationToken); } if (pipe != null) { var request = BuildRequest.Create(language, buildPaths.WorkingDirectory, arguments, keepAlive, libEnvVariable); return(TryCompile(pipe, request, cancellationToken)); } } finally { if (holdsMutex) { clientMutex.ReleaseMutex(); } } } return(null); }