Skip to content

Commit d518c8c

Browse files
committed
Dispose objects properly. Fixes #275
This commit doesn't ensure that an ObjectDisposedException will be thrown if an object is used after it's disposed; a NullReferenceException or some other exception may be thrown instead. These are internal types that should always be used correctly in this code, so tracking incorrect use of Dispose is a low priority.
1 parent db7883c commit d518c8c

File tree

7 files changed

+35
-10
lines changed

7 files changed

+35
-10
lines changed

src/MySqlConnector/Protocol/Serialization/CompressedPayloadHandler.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace MySql.Data.Protocol.Serialization
99
{
10-
internal class CompressedPayloadHandler : IPayloadHandler
10+
internal sealed class CompressedPayloadHandler : IPayloadHandler
1111
{
1212
public CompressedPayloadHandler(IByteHandler byteHandler)
1313
{
@@ -18,6 +18,13 @@ public CompressedPayloadHandler(IByteHandler byteHandler)
1818
m_compressedBufferedByteReader = new BufferedByteReader();
1919
}
2020

21+
public void Dispose()
22+
{
23+
Utility.Dispose(ref m_byteHandler);
24+
Utility.Dispose(ref m_uncompressedStreamByteHandler);
25+
Utility.Dispose(ref m_uncompressedStream);
26+
}
27+
2128
public void StartNewConversation()
2229
{
2330
m_compressedSequenceNumber = 0;
@@ -30,8 +37,11 @@ public IByteHandler ByteHandler
3037
set => throw new NotSupportedException();
3138
}
3239

33-
public ValueTask<ArraySegment<byte>> ReadPayloadAsync(ArraySegmentHolder<byte> cache, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior) =>
34-
ProtocolUtility.ReadPayloadAsync(m_bufferedByteReader, new CompressedByteHandler(this, protocolErrorBehavior), () => -1, cache, protocolErrorBehavior, ioBehavior);
40+
public ValueTask<ArraySegment<byte>> ReadPayloadAsync(ArraySegmentHolder<byte> cache, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
41+
{
42+
using (var compressedByteHandler = new CompressedByteHandler(this, protocolErrorBehavior))
43+
return ProtocolUtility.ReadPayloadAsync(m_bufferedByteReader, compressedByteHandler, () => -1, cache, protocolErrorBehavior, ioBehavior);
44+
}
3545

3646
public ValueTask<int> WritePayloadAsync(ArraySegment<byte> payload, IOBehavior ioBehavior)
3747
{
@@ -232,14 +242,18 @@ private uint ComputeAdler32Checksum(byte[] data, int offset, int length)
232242
}
233243

234244
// CompressedByteHandler implements IByteHandler and delegates reading bytes back to the CompressedPayloadHandler class.
235-
private class CompressedByteHandler : IByteHandler
245+
private sealed class CompressedByteHandler : IByteHandler
236246
{
237247
public CompressedByteHandler(CompressedPayloadHandler compressedPayloadHandler, ProtocolErrorBehavior protocolErrorBehavior)
238248
{
239249
m_compressedPayloadHandler = compressedPayloadHandler;
240250
m_protocolErrorBehavior = protocolErrorBehavior;
241251
}
242252

253+
public void Dispose()
254+
{
255+
}
256+
243257
public ValueTask<int> ReadBytesAsync(ArraySegment<byte> buffer, IOBehavior ioBehavior) =>
244258
m_compressedPayloadHandler.ReadBytesAsync(buffer, m_protocolErrorBehavior, ioBehavior);
245259

@@ -249,9 +263,9 @@ public ValueTask<int> ReadBytesAsync(ArraySegment<byte> buffer, IOBehavior ioBeh
249263
readonly ProtocolErrorBehavior m_protocolErrorBehavior;
250264
}
251265

252-
readonly MemoryStream m_uncompressedStream;
253-
readonly IByteHandler m_uncompressedStreamByteHandler;
254-
readonly IByteHandler m_byteHandler;
266+
MemoryStream m_uncompressedStream;
267+
IByteHandler m_uncompressedStreamByteHandler;
268+
IByteHandler m_byteHandler;
255269
readonly BufferedByteReader m_bufferedByteReader;
256270
readonly BufferedByteReader m_compressedBufferedByteReader;
257271
int m_compressedSequenceNumber;

src/MySqlConnector/Protocol/Serialization/IByteHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace MySql.Data.Protocol.Serialization
55
{
6-
internal interface IByteHandler
6+
internal interface IByteHandler : IDisposable
77
{
88
/// <summary>
99
/// Reads data from this byte handler.

src/MySqlConnector/Protocol/Serialization/IPayloadHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace MySql.Data.Protocol.Serialization
55
{
6-
internal interface IPayloadHandler
6+
internal interface IPayloadHandler : IDisposable
77
{
88
/// <summary>
99
/// Starts a new "conversation" with the MySQL Server. This resets the "<a href="https://dev.mysql.com/doc/internals/en/sequence-id.html">sequence id</a>"

src/MySqlConnector/Protocol/Serialization/SocketByteHandler.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public SocketByteHandler(Socket socket)
1313
m_socketAwaitable = new SocketAwaitable(socketEventArgs);
1414
}
1515

16+
public void Dispose() => m_socketAwaitable.EventArgs.Dispose();
17+
1618
public ValueTask<int> ReadBytesAsync(ArraySegment<byte> buffer, IOBehavior ioBehavior)
1719
{
1820
return (ioBehavior == IOBehavior.Asynchronous) ?

src/MySqlConnector/Protocol/Serialization/StandardPayloadHandler.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ public StandardPayloadHandler(IByteHandler byteHandler)
1111
m_getNextSequenceNumber = () => m_sequenceNumber++;
1212
}
1313

14+
public void Dispose()
15+
{
16+
m_bufferedByteReader = null;
17+
Utility.Dispose(ref m_byteHandler);
18+
}
19+
1420
public void StartNewConversation()
1521
{
1622
m_sequenceNumber = 0;

src/MySqlConnector/Protocol/Serialization/StreamByteHandler.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public StreamByteHandler(Stream stream)
1111
m_stream = stream;
1212
}
1313

14+
public void Dispose() => m_stream.Dispose();
15+
1416
public ValueTask<int> ReadBytesAsync(ArraySegment<byte> buffer, IOBehavior ioBehavior)
1517
{
1618
return (ioBehavior == IOBehavior.Asynchronous) ?

src/MySqlConnector/Serialization/MySqlSession.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,7 @@ private async Task InitSslAsync(ProtocolCapabilities serverCapabilities, Connect
598598
}
599599
catch (Exception ex)
600600
{
601+
sslStream.Dispose();
601602
ShutdownSocket();
602603
m_hostname = "";
603604
lock (m_lock)
@@ -612,7 +613,7 @@ private async Task InitSslAsync(ProtocolCapabilities serverCapabilities, Connect
612613

613614
private void ShutdownSocket()
614615
{
615-
m_payloadHandler = null;
616+
Utility.Dispose(ref m_payloadHandler);
616617
Utility.Dispose(ref m_networkStream);
617618
SafeDispose(ref m_tcpClient);
618619
SafeDispose(ref m_socket);

0 commit comments

Comments
 (0)