THRIFT-1412 Thrift Transport classes should manage the lifetime of objects implementing IDisposable by implementing IDisposable themselves
Patch: Joshua Garvin
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1325013 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/csharp/src/Server/TSimpleServer.cs b/lib/csharp/src/Server/TSimpleServer.cs
index c6fd99e..1099fc1 100644
--- a/lib/csharp/src/Server/TSimpleServer.cs
+++ b/lib/csharp/src/Server/TSimpleServer.cs
@@ -95,39 +95,35 @@
TProtocol outputProtocol = null;
try
{
- client = serverTransport.Accept();
- if (client != null)
- {
- inputTransport = inputTransportFactory.GetTransport(client);
- outputTransport = outputTransportFactory.GetTransport(client);
- inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
- outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
- while (processor.Process(inputProtocol, outputProtocol)) { }
- }
- }
- catch (TTransportException ttx)
- {
- // Client died, just move on
- if (stop)
- {
- logDelegate("TSimpleServer was shutting down, caught " + ttx.GetType().Name);
- }
- }
- catch (Exception x)
- {
- logDelegate(x.ToString());
- }
-
- if (inputTransport != null)
- {
- inputTransport.Close();
- }
-
- if (outputTransport != null)
- {
- outputTransport.Close();
- }
- }
+ using(client = serverTransport.Accept())
+ {
+ if (client != null)
+ {
+ using(inputTransport = inputTransportFactory.GetTransport(client))
+ {
+ using (outputTransport = outputTransportFactory.GetTransport(client))
+ {
+ inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
+ while (processor.Process(inputProtocol, outputProtocol)) { }
+ }
+ }
+ }
+ }
+ }
+ catch (TTransportException ttx)
+ {
+ // Client died, just move on
+ if (stop)
+ {
+ logDelegate("TSimpleServer was shutting down, caught " + ttx.GetType().Name);
+ }
+ }
+ catch (Exception x)
+ {
+ logDelegate(x.ToString());
+ }
+ }
if (stop)
{
diff --git a/lib/csharp/src/Server/TThreadPoolServer.cs b/lib/csharp/src/Server/TThreadPoolServer.cs
index cf8354e..b257fd8 100644
--- a/lib/csharp/src/Server/TThreadPoolServer.cs
+++ b/lib/csharp/src/Server/TThreadPoolServer.cs
@@ -75,16 +75,20 @@
:base(processor, serverTransport, inputTransportFactory, outputTransportFactory,
inputProtocolFactory, outputProtocolFactory, logDel)
{
- if (!ThreadPool.SetMinThreads(minThreadPoolThreads, minThreadPoolThreads))
- {
- throw new Exception("Error: could not SetMinThreads in ThreadPool");
- }
- if (!ThreadPool.SetMaxThreads(maxThreadPoolThreads, maxThreadPoolThreads))
- {
- throw new Exception("Error: could not SetMaxThreads in ThreadPool");
+ lock (typeof(TThreadPoolServer))
+ {
+ if (!ThreadPool.SetMinThreads(minThreadPoolThreads, minThreadPoolThreads))
+ {
+ throw new Exception("Error: could not SetMinThreads in ThreadPool");
+ }
+ if (!ThreadPool.SetMaxThreads(maxThreadPoolThreads, maxThreadPoolThreads))
+ {
+ throw new Exception("Error: could not SetMaxThreads in ThreadPool");
+ }
}
}
+
/// <summary>
/// Use new ThreadPool thread for each new client connection
/// </summary>
diff --git a/lib/csharp/src/Server/TThreadedServer.cs b/lib/csharp/src/Server/TThreadedServer.cs
index f2be073..8e73bb7 100644
--- a/lib/csharp/src/Server/TThreadedServer.cs
+++ b/lib/csharp/src/Server/TThreadedServer.cs
@@ -185,14 +185,18 @@
TProtocol outputProtocol = null;
try
{
- inputTransport = inputTransportFactory.GetTransport(client);
- outputTransport = outputTransportFactory.GetTransport(client);
- inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
- outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
- while (processor.Process(inputProtocol, outputProtocol))
- {
- //keep processing requests until client disconnects
- }
+ using (inputTransport = inputTransportFactory.GetTransport(client))
+ {
+ using (outputTransport = outputTransportFactory.GetTransport(client))
+ {
+ inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
+ while (processor.Process(inputProtocol, outputProtocol))
+ {
+ //keep processing requests until client disconnects
+ }
+ }
+ }
}
catch (TTransportException)
{
@@ -202,15 +206,6 @@
logDelegate("Error: " + x);
}
- if (inputTransport != null)
- {
- inputTransport.Close();
- }
- if (outputTransport != null)
- {
- outputTransport.Close();
- }
-
lock (clientLock)
{
clientThreads.Remove(Thread.CurrentThread);
diff --git a/lib/csharp/src/Transport/TBufferedTransport.cs b/lib/csharp/src/Transport/TBufferedTransport.cs
index 28a855a..14b5db0 100644
--- a/lib/csharp/src/Transport/TBufferedTransport.cs
+++ b/lib/csharp/src/Transport/TBufferedTransport.cs
@@ -22,7 +22,7 @@
namespace Thrift.Transport
{
- public class TBufferedTransport : TTransport
+ public class TBufferedTransport : TTransport, IDisposable
{
private BufferedStream inputBuffer;
private BufferedStream outputBuffer;
@@ -96,5 +96,25 @@
{
outputBuffer.Flush();
}
- }
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (inputBuffer != null)
+ inputBuffer.Dispose();
+ if (outputBuffer != null)
+ outputBuffer.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
}
diff --git a/lib/csharp/src/Transport/TFramedTransport.cs b/lib/csharp/src/Transport/TFramedTransport.cs
index e259f5a..3d43112 100644
--- a/lib/csharp/src/Transport/TFramedTransport.cs
+++ b/lib/csharp/src/Transport/TFramedTransport.cs
@@ -16,12 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-
+using System;
using System.IO;
namespace Thrift.Transport
{
- public class TFramedTransport : TTransport
+ public class TFramedTransport : TTransport, IDisposable
{
protected TTransport transport = null;
protected MemoryStream writeBuffer;
@@ -93,6 +93,7 @@
((i32rd[2] & 0xff) << 8) |
((i32rd[3] & 0xff));
+
byte[] buff = new byte[size];
transport.ReadAll(buff, 0, size);
readBuffer = new MemoryStream(buff);
@@ -133,5 +134,22 @@
// Reserve space for message header to be put right before sending it out
writeBuffer.Write ( header_dummy, 0, header_size );
}
- }
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (readBuffer != null)
+ readBuffer.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
}
diff --git a/lib/csharp/src/Transport/THttpClient.cs b/lib/csharp/src/Transport/THttpClient.cs
index 717907c..106f840 100644
--- a/lib/csharp/src/Transport/THttpClient.cs
+++ b/lib/csharp/src/Transport/THttpClient.cs
@@ -27,7 +27,7 @@
namespace Thrift.Transport
{
- public class THttpClient : TTransport
+ public class THttpClient : TTransport, IDisposable
{
private readonly Uri uri;
private Stream inputStream;
@@ -142,9 +142,11 @@
byte[] data = outputStream.ToArray();
connection.ContentLength = data.Length;
- Stream requestStream = connection.GetRequestStream();
- requestStream.Write(data, 0, data.Length);
- inputStream = connection.GetResponse().GetResponseStream();
+ using (Stream requestStream = connection.GetRequestStream())
+ {
+ requestStream.Write(data, 0, data.Length);
+ inputStream = connection.GetResponse().GetResponseStream();
+ }
}
catch (IOException iox)
{
@@ -156,7 +158,7 @@
}
}
#endif
- private HttpWebRequest CreateRequest()
+ private HttpWebRequest CreateRequest()
{
HttpWebRequest connection = (HttpWebRequest)WebRequest.Create(uri);
@@ -356,5 +358,24 @@
}
#endif
- }
+#region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (inputStream != null)
+ inputStream.Dispose();
+ if (outputStream != null)
+ outputStream.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+#endregion
+ }
}
diff --git a/lib/csharp/src/Transport/TServerSocket.cs b/lib/csharp/src/Transport/TServerSocket.cs
index fd5c662..1ad3bd8 100644
--- a/lib/csharp/src/Transport/TServerSocket.cs
+++ b/lib/csharp/src/Transport/TServerSocket.cs
@@ -126,22 +126,36 @@
{
TcpClient result = server.AcceptTcpClient();
TSocket result2 = new TSocket(result);
- result2.Timeout = clientTimeout;
- if (useBufferedSockets)
- {
- TBufferedTransport result3 = new TBufferedTransport(result2);
- return result3;
- }
- else
- {
- return result2;
- }
- }
- catch (Exception ex)
- {
- throw new TTransportException(ex.ToString());
- }
- }
+ try
+ {
+ result2 = new TSocket(result);
+ result2.Timeout = clientTimeout;
+ if (useBufferedSockets)
+ {
+ TBufferedTransport result3 = new TBufferedTransport(result2);
+ return result3;
+ }
+ else
+ {
+ return result2;
+ }
+ }
+ catch (System.Exception)
+ {
+ // If a TSocket was successfully created, then let
+ // it do proper cleanup of the TcpClient object.
+ if (result2 != null)
+ result2.Dispose();
+ else // Otherwise, clean it up ourselves.
+ ((IDisposable)result).Dispose();
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException(ex.ToString());
+ }
+ }
public override void Close()
{
diff --git a/lib/csharp/src/Transport/TSocket.cs b/lib/csharp/src/Transport/TSocket.cs
index feb5503..c05b6c2 100644
--- a/lib/csharp/src/Transport/TSocket.cs
+++ b/lib/csharp/src/Transport/TSocket.cs
@@ -145,5 +145,24 @@
client = null;
}
}
- }
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (client != null)
+ ((IDisposable)client).Dispose();
+ base.Dispose(disposing);
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
}
diff --git a/lib/csharp/src/Transport/TStreamTransport.cs b/lib/csharp/src/Transport/TStreamTransport.cs
index 60a8412..901b609 100644
--- a/lib/csharp/src/Transport/TStreamTransport.cs
+++ b/lib/csharp/src/Transport/TStreamTransport.cs
@@ -103,5 +103,26 @@
outputStream.Flush();
}
- }
+
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (InputStream != null)
+ InputStream.Dispose();
+ if (OutputStream != null)
+ OutputStream.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
}
diff --git a/lib/csharp/src/Transport/TTransport.cs b/lib/csharp/src/Transport/TTransport.cs
index 3fbc5d6..c03e9c2 100644
--- a/lib/csharp/src/Transport/TTransport.cs
+++ b/lib/csharp/src/Transport/TTransport.cs
@@ -25,7 +25,7 @@
namespace Thrift.Transport
{
- public abstract class TTransport
+ public abstract class TTransport : IDisposable
{
public abstract bool IsOpen
{
@@ -82,5 +82,17 @@
public virtual void EndFlush(IAsyncResult asyncResult)
{
}
- }
+
+ #region " IDisposable Support "
+ // IDisposable
+ protected abstract void Dispose(bool disposing);
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
}