@@ -72,6 +72,7 @@ public abstract class ModelBase : IFullModel, IRecoverable
7272 private readonly object m_eventLock = new object ( ) ;
7373 private readonly object m_flowSendLock = new object ( ) ;
7474 private readonly object m_shutdownLock = new object ( ) ;
75+ private readonly object _rpcLock = new object ( ) ;
7576
7677 private readonly SynchronizedList < ulong > m_unconfirmedSet = new SynchronizedList < ulong > ( ) ;
7778
@@ -358,36 +359,43 @@ public string ConnectionOpen(string virtualHost,
358359 bool insist )
359360 {
360361 var k = new ConnectionOpenContinuation ( ) ;
361- Enqueue ( k ) ;
362- try
363- {
364- _Private_ConnectionOpen ( virtualHost , capabilities , insist ) ;
365- }
366- catch ( AlreadyClosedException )
362+ lock ( _rpcLock )
367363 {
368- // let continuation throw OperationInterruptedException,
369- // which is a much more suitable exception before connection
370- // negotiation finishes
364+ Enqueue ( k ) ;
365+ try
366+ {
367+ _Private_ConnectionOpen ( virtualHost , capabilities , insist ) ;
368+ }
369+ catch ( AlreadyClosedException )
370+ {
371+ // let continuation throw OperationInterruptedException,
372+ // which is a much more suitable exception before connection
373+ // negotiation finishes
374+ }
375+ k . GetReply ( HandshakeContinuationTimeout ) ;
371376 }
372- k . GetReply ( HandshakeContinuationTimeout ) ;
377+
373378 return k . m_knownHosts ;
374379 }
375380
376381 public ConnectionSecureOrTune ConnectionSecureOk ( byte [ ] response )
377382 {
378383 var k = new ConnectionStartRpcContinuation ( ) ;
379- Enqueue ( k ) ;
380- try
384+ lock ( _rpcLock )
381385 {
382- _Private_ConnectionSecureOk ( response ) ;
383- }
384- catch ( AlreadyClosedException )
385- {
386- // let continuation throw OperationInterruptedException,
387- // which is a much more suitable exception before connection
388- // negotiation finishes
386+ Enqueue ( k ) ;
387+ try
388+ {
389+ _Private_ConnectionSecureOk ( response ) ;
390+ }
391+ catch ( AlreadyClosedException )
392+ {
393+ // let continuation throw OperationInterruptedException,
394+ // which is a much more suitable exception before connection
395+ // negotiation finishes
396+ }
397+ k . GetReply ( HandshakeContinuationTimeout ) ;
389398 }
390- k . GetReply ( HandshakeContinuationTimeout ) ;
391399 return k . m_result ;
392400 }
393401
@@ -397,19 +405,22 @@ public ConnectionSecureOrTune ConnectionStartOk(IDictionary<string, object> clie
397405 string locale )
398406 {
399407 var k = new ConnectionStartRpcContinuation ( ) ;
400- Enqueue ( k ) ;
401- try
402- {
403- _Private_ConnectionStartOk ( clientProperties , mechanism ,
404- response , locale ) ;
405- }
406- catch ( AlreadyClosedException )
408+ lock ( _rpcLock )
407409 {
408- // let continuation throw OperationInterruptedException,
409- // which is a much more suitable exception before connection
410- // negotiation finishes
410+ Enqueue ( k ) ;
411+ try
412+ {
413+ _Private_ConnectionStartOk ( clientProperties , mechanism ,
414+ response , locale ) ;
415+ }
416+ catch ( AlreadyClosedException )
417+ {
418+ // let continuation throw OperationInterruptedException,
419+ // which is a much more suitable exception before connection
420+ // negotiation finishes
421+ }
422+ k . GetReply ( HandshakeContinuationTimeout ) ;
411423 }
412- k . GetReply ( HandshakeContinuationTimeout ) ;
413424 return k . m_result ;
414425 }
415426
@@ -456,8 +467,11 @@ public void HandleCommand(ISession session, Command cmd)
456467 public MethodBase ModelRpc ( MethodBase method , ContentHeaderBase header , byte [ ] body )
457468 {
458469 var k = new SimpleBlockingRpcContinuation ( ) ;
459- TransmitAndEnqueue ( new Command ( method , header , body ) , k ) ;
460- return k . GetReply ( this . ContinuationTimeout ) . Method ;
470+ lock ( _rpcLock )
471+ {
472+ TransmitAndEnqueue ( new Command ( method , header , body ) , k ) ;
473+ return k . GetReply ( this . ContinuationTimeout ) . Method ;
474+ }
461475 }
462476
463477 public void ModelSend ( MethodBase method , ContentHeaderBase header , byte [ ] body )
@@ -1146,10 +1160,12 @@ public void BasicCancel(string consumerTag)
11461160 {
11471161 var k = new BasicConsumerRpcContinuation { m_consumerTag = consumerTag } ;
11481162
1149- Enqueue ( k ) ;
1150-
1151- _Private_BasicCancel ( consumerTag , false ) ;
1152- k . GetReply ( this . ContinuationTimeout ) ;
1163+ lock ( _rpcLock )
1164+ {
1165+ Enqueue ( k ) ;
1166+ _Private_BasicCancel ( consumerTag , false ) ;
1167+ k . GetReply ( this . ContinuationTimeout ) ;
1168+ }
11531169 lock ( m_consumers )
11541170 {
11551171 m_consumers . Remove ( consumerTag ) ;
@@ -1180,12 +1196,15 @@ public string BasicConsume(string queue,
11801196
11811197 var k = new BasicConsumerRpcContinuation { m_consumer = consumer } ;
11821198
1183- Enqueue ( k ) ;
1184- // Non-nowait. We have an unconventional means of getting
1185- // the RPC response, but a response is still expected.
1186- _Private_BasicConsume ( queue , consumerTag , noLocal , autoAck , exclusive ,
1187- /*nowait:*/ false , arguments ) ;
1188- k . GetReply ( this . ContinuationTimeout ) ;
1199+ lock ( _rpcLock )
1200+ {
1201+ Enqueue ( k ) ;
1202+ // Non-nowait. We have an unconventional means of getting
1203+ // the RPC response, but a response is still expected.
1204+ _Private_BasicConsume ( queue , consumerTag , noLocal , autoAck , exclusive ,
1205+ /*nowait:*/ false , arguments ) ;
1206+ k . GetReply ( this . ContinuationTimeout ) ;
1207+ }
11891208 string actualConsumerTag = k . m_consumerTag ;
11901209
11911210 return actualConsumerTag ;
@@ -1195,9 +1214,13 @@ public BasicGetResult BasicGet(string queue,
11951214 bool autoAck )
11961215 {
11971216 var k = new BasicGetRpcContinuation ( ) ;
1198- Enqueue ( k ) ;
1199- _Private_BasicGet ( queue , autoAck ) ;
1200- k . GetReply ( this . ContinuationTimeout ) ;
1217+ lock ( _rpcLock )
1218+ {
1219+ Enqueue ( k ) ;
1220+ _Private_BasicGet ( queue , autoAck ) ;
1221+ k . GetReply ( this . ContinuationTimeout ) ;
1222+ }
1223+
12011224 return k . m_result ;
12021225 }
12031226
@@ -1261,9 +1284,12 @@ public void BasicRecover(bool requeue)
12611284 {
12621285 var k = new SimpleBlockingRpcContinuation ( ) ;
12631286
1264- Enqueue ( k ) ;
1265- _Private_BasicRecover ( requeue ) ;
1266- k . GetReply ( this . ContinuationTimeout ) ;
1287+ lock ( _rpcLock )
1288+ {
1289+ Enqueue ( k ) ;
1290+ _Private_BasicRecover ( requeue ) ;
1291+ k . GetReply ( this . ContinuationTimeout ) ;
1292+ }
12671293 }
12681294
12691295 public abstract void BasicRecoverAsync ( bool requeue ) ;
@@ -1559,9 +1585,12 @@ private QueueDeclareOk QueueDeclare(string queue, bool passive, bool durable, bo
15591585 bool autoDelete , IDictionary < string , object > arguments )
15601586 {
15611587 var k = new QueueDeclareRpcContinuation ( ) ;
1562- Enqueue ( k ) ;
1563- _Private_QueueDeclare ( queue , passive , durable , exclusive , autoDelete , false , arguments ) ;
1564- k . GetReply ( this . ContinuationTimeout ) ;
1588+ lock ( _rpcLock )
1589+ {
1590+ Enqueue ( k ) ;
1591+ _Private_QueueDeclare ( queue , passive , durable , exclusive , autoDelete , false , arguments ) ;
1592+ k . GetReply ( this . ContinuationTimeout ) ;
1593+ }
15651594 return k . m_result ;
15661595 }
15671596
0 commit comments