public void Dispose() { if (service != null && !service.IsClosed) { // now free the Compiler object service.WriteMessage(CompilerFreeMessage + ":" + id); string handshake = service.ReadMessage(); if (handshake != JobFinishedMessage) { DebugWriteLine("Job Error: " + handshake); } else { DebugWriteLine("Job Terminated: " + handshake); } } service?.Close(); // we can only write one message at a time. }
public bool Compile(CommandLineOptions options, TextWriter log) { bool finished = false; bool result = false; NamedPipe service = Connect(log); CompilerOutputStream output = new CompilerOutputStream(log); options.compilerId = id; StringWriter writer = new StringWriter(); XmlSerializer serializer = new XmlSerializer(typeof(CommandLineOptions)); serializer.Serialize(writer, options); service.WriteMessage(writer.ToString()); try { while (!finished && !service.IsClosed) { string msg = service.ReadMessage(); DebugWriteLine(msg); int i = msg.IndexOf(':'); if (i > 0) { string sev = msg.Substring(0, i); SeverityKind severity = SeverityKind.Info; Enum.TryParse <SeverityKind>(sev, out severity); msg = msg.Substring(i + 2); if (msg.StartsWith(JobFinishedMessage)) { string tail = msg.Substring(JobFinishedMessage.Length); finished = true; bool.TryParse(tail, out result); } else { output.WriteMessage(msg, severity); } } else { log.WriteLine(msg); } } } catch (Exception) { result = false; output.WriteMessage("PCompilerService is gone, did someone kill it? Perhaps the P build is happening in parallel?", SeverityKind.Error); finished = true; } return(result); }
private NamedPipe Connect(TextWriter log) { Mutex processLock = new Mutex(false, "PCompilerService"); processLock.WaitOne(); try { if (service == null) { service = new NamedPipe(ServerPipeName); if (!service.Connect()) { ProcessStartInfo info = new ProcessStartInfo(); info.FileName = typeof(CompilerServiceClient).Assembly.Location; info.WindowStyle = ProcessWindowStyle.Hidden; Process p = Process.Start(info); if (!service.Connect()) { log.WriteLine("Cannot start the CompilerService?"); service = null; return(null); } else { // now lock a Compiler object until we re disposed so we can get better // performance by sharing the same Compiler across compile, link and test. service.WriteMessage(CompilerLockMessage); this.id = service.ReadMessage(); } } } } finally { processLock.ReleaseMutex(); } return(service); }
private void OnClientConnected(object sender, NamedPipe pipe) { while (!pipe.IsClosed) { // the protocol after client connects is to send a job, we send back results until we // send the <job-finished> message, then we expect a "<job-finished>" handshake from client // or the client sends another job. string msg = pipe.ReadMessage(); if (msg == null) { // pipe is closing. } else if (msg == CompilerServiceClient.CompilerLockMessage) { HandleLockMessage(pipe); } else if (msg.StartsWith(CompilerServiceClient.CompilerFreeMessage)) { // this session is done, double handshake. HandleFreeMessage(pipe, msg); } else if (!string.IsNullOrEmpty(msg)) { try { doMoreWork = true; var output = new SerializedOutput(pipe); bool result = ProcessJob(msg, output); // now make sure client gets the JobFinishedMessage message! output.WriteMessage(CompilerServiceClient.JobFinishedMessage + result, SeverityKind.Info); output.Flush(); } catch (Exception) { // deserialization of the job failed, so ignore it. } } } pipe.Close(); }