[xharness] Fix log stream handling. (#1494)
Don't create multiple writer streams for the same underlying file, instead store the writer stream on the log instance, and return it whenever needed. This fixes an issue where there would be multiple writer streams, which could cause exceptions when creating more writer streams (access defined errors because the file is already open).
This commit is contained in:
Родитель
c21f8d31ca
Коммит
a02fb1d62e
|
@ -29,7 +29,7 @@ namespace xharness
|
||||||
throw new NotSupportedException ();
|
throw new NotSupportedException ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual TextWriter GetWriter ()
|
public virtual StreamWriter GetWriter ()
|
||||||
{
|
{
|
||||||
throw new NotSupportedException ();
|
throw new NotSupportedException ();
|
||||||
}
|
}
|
||||||
|
@ -72,22 +72,18 @@ namespace xharness
|
||||||
public string Path;
|
public string Path;
|
||||||
StreamWriter writer;
|
StreamWriter writer;
|
||||||
|
|
||||||
public LogFile (string description, string path)
|
public LogFile (string description, string path, bool append = true)
|
||||||
: base (description)
|
: base (description)
|
||||||
{
|
{
|
||||||
Path = path;
|
Path = path;
|
||||||
|
|
||||||
|
writer = new StreamWriter (new FileStream (Path, append ? FileMode.Append : FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read));
|
||||||
|
writer.AutoFlush = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void WriteImpl (string value)
|
protected override void WriteImpl (string value)
|
||||||
{
|
{
|
||||||
lock (this) {
|
writer.Write (value);
|
||||||
using (var str = new FileStream (Path, FileMode.Append, FileAccess.Write, FileShare.Read)) {
|
|
||||||
using (var writer = new StreamWriter (str)) {
|
|
||||||
writer.Write (value);
|
|
||||||
writer.Flush ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string FullPath {
|
public override string FullPath {
|
||||||
|
@ -101,9 +97,9 @@ namespace xharness
|
||||||
return new StreamReader (new FileStream (Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
return new StreamReader (new FileStream (Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TextWriter GetWriter ()
|
public override StreamWriter GetWriter ()
|
||||||
{
|
{
|
||||||
return writer ?? (writer = new StreamWriter (new FileStream (Path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read)));
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose (bool disposing)
|
protected override void Dispose (bool disposing)
|
||||||
|
@ -134,9 +130,9 @@ namespace xharness
|
||||||
return new StreamReader (new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
return new StreamReader (new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TextWriter GetWriter ()
|
public override StreamWriter GetWriter ()
|
||||||
{
|
{
|
||||||
return writer ?? (writer = new StreamWriter (fs));
|
return writer ?? (writer = new StreamWriter (fs) { AutoFlush = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
public LogStream (string description, string path)
|
public LogStream (string description, string path)
|
||||||
|
@ -210,9 +206,9 @@ namespace xharness
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TextWriter GetWriter ()
|
public override StreamWriter GetWriter ()
|
||||||
{
|
{
|
||||||
return Console.Out;
|
return new StreamWriter (Console.OpenStandardOutput ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override StreamReader GetReader ()
|
public override StreamReader GetReader ()
|
||||||
|
|
|
@ -85,10 +85,8 @@ namespace xharness
|
||||||
break;
|
break;
|
||||||
case "/Finish":
|
case "/Finish":
|
||||||
if (!finished) {
|
if (!finished) {
|
||||||
using (var writer = new StreamWriter (OutputStream)) {
|
OutputWriter.Write (data);
|
||||||
writer.Write (data);
|
OutputWriter.Flush ();
|
||||||
writer.Flush ();
|
|
||||||
}
|
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace xharness
|
||||||
{
|
{
|
||||||
public abstract class SimpleListener : IDisposable
|
public abstract class SimpleListener : IDisposable
|
||||||
{
|
{
|
||||||
FileStream output_stream;
|
StreamWriter output_writer;
|
||||||
|
|
||||||
protected ManualResetEvent stopped = new ManualResetEvent (false);
|
protected ManualResetEvent stopped = new ManualResetEvent (false);
|
||||||
protected ManualResetEvent connected = new ManualResetEvent (false);
|
protected ManualResetEvent connected = new ManualResetEvent (false);
|
||||||
|
@ -23,9 +23,9 @@ namespace xharness
|
||||||
protected abstract void Start ();
|
protected abstract void Start ();
|
||||||
protected abstract void Stop ();
|
protected abstract void Stop ();
|
||||||
|
|
||||||
public FileStream OutputStream {
|
public StreamWriter OutputWriter {
|
||||||
get {
|
get {
|
||||||
return output_stream;
|
return output_writer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,19 +34,13 @@ namespace xharness
|
||||||
Log.WriteLine ("Connection from {0} saving logs to {1}", remote, TestLog.FullPath);
|
Log.WriteLine ("Connection from {0} saving logs to {1}", remote, TestLog.FullPath);
|
||||||
connected.Set ();
|
connected.Set ();
|
||||||
|
|
||||||
if (output_stream != null) {
|
if (output_writer == null) {
|
||||||
output_stream.Flush ();
|
output_writer = TestLog.GetWriter ();
|
||||||
output_stream.Dispose ();
|
|
||||||
}
|
|
||||||
|
|
||||||
var fs = TestLog.FileStream;
|
// a few extra bits of data only available from this side
|
||||||
// a few extra bits of data only available from this side
|
output_writer.WriteLine ($"[Local Date/Time:\t{DateTime.Now}]");
|
||||||
string header = String.Format ("[Local Date/Time:\t{1}]{0}[Remote Address:\t{2}]{0}",
|
output_writer.WriteLine ($"[Remote Address:\t{remote}]");
|
||||||
Environment.NewLine, DateTime.Now, remote);
|
}
|
||||||
byte [] array = Encoding.UTF8.GetBytes (header);
|
|
||||||
fs.Write (array, 0, array.Length);
|
|
||||||
fs.Flush ();
|
|
||||||
output_stream = fs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,8 +77,8 @@ namespace xharness
|
||||||
#region IDisposable Support
|
#region IDisposable Support
|
||||||
protected virtual void Dispose (bool disposing)
|
protected virtual void Dispose (bool disposing)
|
||||||
{
|
{
|
||||||
if (output_stream != null)
|
if (output_writer != null)
|
||||||
output_stream.Dispose ();
|
output_writer.Dispose ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose ()
|
public void Dispose ()
|
||||||
|
|
|
@ -53,11 +53,11 @@ namespace xharness
|
||||||
bool Processing (TcpClient client)
|
bool Processing (TcpClient client)
|
||||||
{
|
{
|
||||||
Connected (client.Client.RemoteEndPoint.ToString ());
|
Connected (client.Client.RemoteEndPoint.ToString ());
|
||||||
FileStream fs = OutputStream;
|
|
||||||
// now simply copy what we receive
|
// now simply copy what we receive
|
||||||
int i;
|
int i;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
NetworkStream stream = client.GetStream ();
|
NetworkStream stream = client.GetStream ();
|
||||||
|
var fs = OutputWriter.BaseStream;
|
||||||
while ((i = stream.Read (buffer, 0, buffer.Length)) != 0) {
|
while ((i = stream.Read (buffer, 0, buffer.Length)) != 0) {
|
||||||
fs.Write (buffer, 0, i);
|
fs.Write (buffer, 0, i);
|
||||||
fs.Flush ();
|
fs.Flush ();
|
||||||
|
@ -69,7 +69,6 @@ namespace xharness
|
||||||
// the ip address we're reachable on.
|
// the ip address we're reachable on.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fs.Flush ();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче