Example #1
0
        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);
        }