internal static async Task <ServerData> CreateServer( string pipeName = null, ICompilerServerHost compilerServerHost = null, bool failingServer = false, string tempPath = null) { // The total pipe path must be < 92 characters on Unix, so trim this down to 10 chars pipeName = pipeName ?? Guid.NewGuid().ToString().Substring(0, 10); compilerServerHost = compilerServerHost ?? DesktopBuildServerController.CreateCompilerServerHost(); tempPath = tempPath ?? Path.GetTempPath(); var clientConnectionHost = DesktopBuildServerController.CreateClientConnectionHostForServerHost(compilerServerHost, pipeName); if (failingServer) { clientConnectionHost = new FailingClientConnectionHost(clientConnectionHost); } var serverStatsSource = new TaskCompletionSource <ServerStats>(); var serverListenSource = new TaskCompletionSource <bool>(); var cts = new CancellationTokenSource(); var mutexName = BuildServerConnection.GetServerMutexName(pipeName); var task = Task.Run(() => { var listener = new TestableDiagnosticListener(); listener.Listening += (sender, e) => { serverListenSource.TrySetResult(true); }; try { DesktopBuildServerController.RunServer( pipeName, tempPath, clientConnectionHost, listener, keepAlive: TimeSpan.FromMilliseconds(-1), cancellationToken: cts.Token); } finally { var serverStats = new ServerStats(connections: listener.ConnectionCount, completedConnections: listener.CompletedCount); serverStatsSource.SetResult(serverStats); } }); // The contract of this function is that it will return once the server has started. Spin here until // we can verify the server has started or simply failed to start. while (BuildServerConnection.WasServerMutexOpen(mutexName) != true && !task.IsCompleted) { await Task.Yield(); } if (task.IsFaulted) { throw task.Exception; } return(new ServerData(cts, pipeName, serverStatsSource.Task, serverListenSource.Task)); }
internal static ServerData CreateServer( string pipeName = null, ICompilerServerHost compilerServerHost = null, bool failingServer = false) { pipeName = pipeName ?? Guid.NewGuid().ToString(); compilerServerHost = compilerServerHost ?? DesktopBuildServerController.CreateCompilerServerHost(); var clientConnectionHost = DesktopBuildServerController.CreateClientConnectionHostForServerHost(compilerServerHost, pipeName); if (failingServer) { clientConnectionHost = new FailingClientConnectionHost(clientConnectionHost); } var serverStatsSource = new TaskCompletionSource <ServerStats>(); var serverListenSource = new TaskCompletionSource <bool>(); var cts = new CancellationTokenSource(); var mutexName = BuildServerConnection.GetServerMutexName(pipeName); var thread = new Thread(_ => { var listener = new TestableDiagnosticListener(); listener.Listening += (sender, e) => { serverListenSource.TrySetResult(true); }; try { DesktopBuildServerController.RunServer( pipeName, clientConnectionHost, listener, keepAlive: TimeSpan.FromMilliseconds(-1), cancellationToken: cts.Token); } finally { var serverStats = new ServerStats(connections: listener.ConnectionCount, completedConnections: listener.CompletedCount); serverStatsSource.SetResult(serverStats); } }); thread.Start(); // The contract of this function is that it will return once the server has started. Spin here until // we can verify the server has started or simply failed to start. while (BuildServerConnection.WasServerMutexOpen(mutexName) != true && thread.IsAlive) { Thread.Yield(); } return(new ServerData(cts, pipeName, serverStatsSource.Task, serverListenSource.Task)); }