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(); }
private void ProcessJob(string msg) { Interlocked.Increment(ref busyCount); NamedPipe clientPipe = null; try { XmlSerializer s = new XmlSerializer(typeof(CommandLineOptions)); CommandLineOptions options = (CommandLineOptions)s.Deserialize(new StringReader(msg)); if (!string.IsNullOrEmpty(options.pipeName)) { clientPipe = new NamedPipe(options.pipeName, false); clientPipe.Connect(); } var output = new SerializedOutput(clientPipe); bool retry = true; bool masterCreated = false; while (retry) { retry = false; // We have to serialize compiler jobs, the Compiler is not threadsafe. lock (compilerlock) { if (master == null) { masterCreated = true; output.WriteMessage("Generating P compiler", SeverityKind.Info); master = new Compiler(false); } // share the compiled P program across compiler instances. Compiler compiler = master; // new Compiler(master); bool result = false; try { result = compiler.Compile(options.inputFileName, new SerializedOutput(clientPipe), options); } catch (Exception ex) { if (!masterCreated) { // sometimes the compiler gets out of whack, and rebuilding it solves the problem. retry = true; master = null; } else { output.WriteMessage("Compile failed: " + ex.ToString(), SeverityKind.Error); } } if (!retry) { compiler.Log.WriteMessage("finished:" + result, SeverityKind.Info); } } } Thread.Sleep(1000); } finally { if (clientPipe != null) { clientPipe.Close(); } Interlocked.Decrement(ref busyCount); } }