internal static ServerData Create( ICompilerServerLogger logger, string pipeName = null, ICompilerServerHost compilerServerHost = null, IClientConnectionHost clientConnectionHost = null, TimeSpan?keepAlive = null) { // The total pipe path must be < 92 characters on Unix, so trim this down to 10 chars pipeName ??= ServerUtil.GetPipeName(); compilerServerHost ??= BuildServerController.CreateCompilerServerHost(logger); clientConnectionHost ??= BuildServerController.CreateClientConnectionHost(pipeName, logger); keepAlive ??= TimeSpan.FromMilliseconds(-1); var listener = new TestableDiagnosticListener(); var serverListenSource = new TaskCompletionSource <bool>(); var cts = new CancellationTokenSource(); var mutexName = BuildServerConnection.GetServerMutexName(pipeName); var task = Task.Run(() => { BuildServerController.CreateAndRunServer( pipeName, compilerServerHost, clientConnectionHost, listener, keepAlive: keepAlive, cancellationToken: cts.Token); return(listener); }); return(new ServerData(cts, pipeName, logger, task)); }
internal static async Task <ServerData> CreateServer( string pipeName = null, ICompilerServerHost compilerServerHost = null, IClientConnectionHost clientConnectionHost = null, TimeSpan?keepAlive = null) { // The total pipe path must be < 92 characters on Unix, so trim this down to 10 chars pipeName ??= Guid.NewGuid().ToString().Substring(0, 10); compilerServerHost ??= BuildServerController.CreateCompilerServerHost(); clientConnectionHost ??= BuildServerController.CreateClientConnectionHost(pipeName); keepAlive ??= TimeSpan.FromMilliseconds(-1); var listener = new TestableDiagnosticListener(); var listenerTaskCompletionSource = new TaskCompletionSource <TestableDiagnosticListener>(); var serverListenSource = new TaskCompletionSource <bool>(); var cts = new CancellationTokenSource(); var mutexName = BuildServerConnection.GetServerMutexName(pipeName); var task = Task.Run(() => { try { BuildServerController.CreateAndRunServer( pipeName, compilerServerHost, clientConnectionHost, listener, keepAlive: keepAlive, cancellationToken: cts.Token); } finally { listenerTaskCompletionSource.SetResult(listener); } }); // 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, listenerTaskCompletionSource.Task)); }