Skip to content

Commit 664c8e9

Browse files
michaelklishinlukebakken
authored andcommitted
Reintroduce locking around socket writes
when transmitting multiple frames at once. While changes in #350, #354 are supposed to be safe, there's some evidence (#681) that sometimes they are not which leads to incorrect byte stream interleaving on the wire. Update API approval test expectations Re-introduce lock for all socket writes The official `NetworkStream` docs are confusing: https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.networkstream?view=netframework-4.5.1 > Read and write operations can be performed simultaneously on an instance of the NetworkStream class without the need for synchronization. As long as there is one unique thread for the write operations and one unique thread for the read operations, there will be no cross-interference between read and write threads and no synchronization is required. This is a poorly-written way to say "multiple threads must be synchronized". Fixes #681 Update API approval test expectations
1 parent d0c5123 commit 664c8e9

File tree

2 files changed

+3
-11
lines changed

2 files changed

+3
-11
lines changed

projects/client/RabbitMQ.Client/src/client/impl/Connection.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ public event EventHandler<ConnectionRecoveryErrorEventArgs> ConnectionRecoveryEr
254254
}
255255
}
256256
}
257+
257258
public string ClientProvidedName { get; private set; }
258259

259260
public ushort ChannelMax

projects/client/RabbitMQ.Client/src/client/impl/SocketFrameHandler.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,8 @@ public class SocketFrameHandler : IFrameHandler
7979
private readonly ITcpClient m_socket;
8080
private readonly NetworkBinaryWriter m_writer;
8181
private readonly object _semaphore = new object();
82-
private readonly object _sslStreamLock = new object();
82+
private readonly object _streamLock = new object();
8383
private bool _closed;
84-
private bool _ssl = false;
8584
public SocketFrameHandler(AmqpTcpEndpoint endpoint,
8685
Func<AddressFamily, ITcpClient> socketFactory,
8786
TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout)
@@ -112,7 +111,6 @@ public SocketFrameHandler(AmqpTcpEndpoint endpoint,
112111
try
113112
{
114113
netstream = SslHelper.TcpUpgrade(netstream, endpoint.Ssl);
115-
_ssl = true;
116114
}
117115
catch (Exception)
118116
{
@@ -249,14 +247,7 @@ public void WriteFrameSet(IList<OutboundFrame> frames)
249247

250248
private void Write(ArraySegment<byte> bufferSegment)
251249
{
252-
if(_ssl)
253-
{
254-
lock (_sslStreamLock)
255-
{
256-
m_writer.Write(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count);
257-
}
258-
}
259-
else
250+
lock (_streamLock)
260251
{
261252
m_writer.Write(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count);
262253
}

0 commit comments

Comments
 (0)