private void Process() { var command = queue.Pop(delay, new Command { Action = idle }); if (command.Quit) { quit = true; } if (command.Handler == null) { command.Handler = handler; } if (command.Action != null) { try { command.Action(); } catch (Exception ex) { command.Handler?.Invoke(ex); } } }
//must keep returning null after reader closed //to ensure next readline returns null after nested reads public string ReadLine() { if (closed) { return(null); } var line = queue.Pop(1, null); while (line == null) { line = queue.Pop(1, null); } if (line == Environ.NewLines) { closed = true; } if (line == Environ.NewLines) { return(null); } return(line); }
public static void Interactive(IStream io, Args args) { var thread = Thread.CurrentThread.Name; var reader = new Runner(new Runner.Args() { ThreadName = string.Format("{0}_R", thread) }); var erroer = new Runner(new Runner.Args() { ThreadName = string.Format("{0}_W", thread) }); using (reader) using (erroer) { var process = new DaemonProcess(args); //eof below must close process immediatelly //to ensure exited message happens after real exit using (process) { io.WriteLine("Process {0} has started", process.Id); var queue = new LockedQueue <bool>(); reader.Run(() => { var line = process.ReadLine(); while (line != null) { Logger.Trace("<o:{0} {1}", process.Id, line); io.WriteLine(line); line = process.ReadLine(); } Logger.Trace("<o:{0} EOF", process.Id); }); reader.Run(() => queue.Push(true)); erroer.Run(() => { var line = process.ReadError(); while (line != null) { Logger.Trace("<e:{0} {1}", process.Id, line); line = process.ReadError(); } Logger.Trace("<e:{0} EOF", process.Id); }); erroer.Run(() => queue.Push(true)); while (true) { //non blocking readline needed to notice reader exit var line = io.TryReadLine(out var eof); if (eof) { Logger.Trace("EOF input > process"); } if (eof) { break; } if (line != null) { Logger.Trace("i:{0}> {1}", process.Id, line); process.WriteLine(line); } if (queue.Pop(1, false)) { break; } } } //previous loop may swallow exit! by feeding it to process //unit test should wait for syncing message below before exit! io.WriteLine("Process {0} has exited", process.Id); } }