Skip to content

Commit a569005

Browse files
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.
1 parent 027e8ed commit a569005

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ public void TransmitAsFrameSet(int channelNumber, Connection connection)
134134
}
135135
}
136136

137-
connection.WriteFrameSet(frames);
137+
// synchronise multi-frame writes as particularly risky
138+
lock(connection.SocketWriteLock) {
139+
connection.WriteFrameSet(frames);
140+
}
138141
}
139142

140143

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ namespace RabbitMQ.Client.Framing.Impl
6666
public class Connection : IConnection
6767
{
6868
private readonly object m_eventLock = new object();
69+
private object m_socketWriteLock = new object();
6970

7071
///<summary>Heartbeat frame for transmission. Reusable across connections.</summary>
7172
private readonly EmptyOutboundFrame m_heartbeatFrame = new EmptyOutboundFrame();
@@ -271,6 +272,9 @@ public event EventHandler<ConnectionRecoveryErrorEventArgs> ConnectionRecoveryEr
271272
}
272273
}
273274
}
275+
276+
public object SocketWriteLock { get; }
277+
274278
public string ClientProvidedName { get; private set; }
275279

276280
public ushort ChannelMax

0 commit comments

Comments
 (0)