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. }
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(); }
public bool Compile(CommandLineOptions options, TextWriter log) { service = new NamedPipe(ServerPipeName, false); Mutex processLock = new Mutex(false, "PCompilerService"); processLock.WaitOne(); try { 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?"); return(false); } } } finally { processLock.ReleaseMutex(); } Guid clientPipe = Guid.NewGuid(); string clientPipeName = clientPipe.ToString() + "-CompilerServiceClient"; client = new NamedPipe(clientPipeName, true); if (!client.Connect()) { log.WriteLine("weird, the process that launched this job is gone?"); return(false); } AutoResetEvent msgEvent = new AutoResetEvent(false); bool finished = false; bool result = false; CompilerOutputStream output = new CompilerOutputStream(log); client.MessageArrived += (s2, e2) => { string msg = e2.Message; int i = msg.IndexOf(':'); if (i > 0) { string sev = msg.Substring(0, i); msg = msg.Substring(i + 2); if (msg.StartsWith("finished:")) { i = msg.IndexOf(':'); string tail = msg.Substring(i + 1); finished = true; bool.TryParse(tail, out result); msgEvent.Set(); } else { SeverityKind severity = SeverityKind.Info; Enum.TryParse <SeverityKind>(sev, out severity); output.WriteMessage(msg, severity); } } else { log.WriteLine(e2.Message); } }; options.pipeName = clientPipeName; StringWriter writer = new StringWriter(); XmlSerializer serializer = new XmlSerializer(typeof(CommandLineOptions)); serializer.Serialize(writer, options); service.WriteMessage(writer.ToString()); while (!finished) { msgEvent.WaitOne(1000); if (client.IsClosed) { result = false; output.WriteMessage("PCompilerService is gone, did someone kill it? Perhaps the P build is happening in parallel?", SeverityKind.Error); finished = true; } } service.Close(); client.Close(); return(result); }