42
42
using RabbitMQ . Client . Exceptions ;
43
43
using RabbitMQ . Client . Impl ;
44
44
using RabbitMQ . Util ;
45
+
45
46
using System ;
46
47
using System . Collections . Generic ;
47
48
using System . IO ;
@@ -98,10 +99,6 @@ public class Connection : IConnection
98
99
private Timer _heartbeatReadTimer ;
99
100
private AutoResetEvent m_heartbeatRead = new AutoResetEvent ( false ) ;
100
101
101
- private readonly object _heartBeatReadLock = new object ( ) ;
102
- private readonly object _heartBeatWriteLock = new object ( ) ;
103
- private bool m_hasDisposedHeartBeatReadTimer ;
104
- private bool m_hasDisposedHeartBeatWriteTimer ;
105
102
private Task _mainLoopTask ;
106
103
107
104
private static string version = typeof ( Connection ) . Assembly
@@ -519,8 +516,6 @@ public void EnsureIsOpen()
519
516
// Only call at the end of the Mainloop or HeartbeatLoop
520
517
public void FinishClose ( )
521
518
{
522
- // Notify hearbeat loops that they can leave
523
- m_heartbeatRead . Set ( ) ;
524
519
m_closed = true ;
525
520
MaybeStopHeartbeatTimers ( ) ;
526
521
@@ -948,19 +943,15 @@ public void MaybeStartHeartbeatTimers()
948
943
{
949
944
if ( Heartbeat != 0 )
950
945
{
951
- m_hasDisposedHeartBeatReadTimer = false ;
952
- m_hasDisposedHeartBeatWriteTimer = false ;
953
- lock ( _heartBeatWriteLock )
946
+ if ( _heartbeatWriteTimer == null )
954
947
{
955
948
_heartbeatWriteTimer = new Timer ( HeartbeatWriteTimerCallback , null , Timeout . Infinite , Timeout . Infinite ) ;
956
-
957
949
_heartbeatWriteTimer . Change ( 200 , Timeout . Infinite ) ;
958
950
}
959
951
960
- lock ( _heartBeatReadLock )
952
+ if ( _heartbeatReadTimer == null )
961
953
{
962
954
_heartbeatReadTimer = new Timer ( HeartbeatReadTimerCallback , null , Timeout . Infinite , Timeout . Infinite ) ;
963
-
964
955
_heartbeatReadTimer . Change ( 300 , Timeout . Infinite ) ;
965
956
}
966
957
}
@@ -973,75 +964,69 @@ public void StartMainLoop(bool useBackgroundThread)
973
964
974
965
public void HeartbeatReadTimerCallback ( object state )
975
966
{
976
- lock ( _heartBeatReadLock )
967
+ if ( _heartbeatReadTimer == null )
977
968
{
978
- if ( m_hasDisposedHeartBeatReadTimer )
979
- {
980
- return ;
981
- }
969
+ return ;
970
+ }
982
971
983
- bool shouldTerminate = false ;
972
+ bool shouldTerminate = false ;
984
973
985
- try
974
+ try
975
+ {
976
+ if ( ! m_closed )
986
977
{
987
- if ( ! m_closed )
978
+ if ( ! m_heartbeatRead . WaitOne ( 0 ) )
988
979
{
989
- if ( ! m_heartbeatRead . WaitOne ( 0 ) )
990
- {
991
- m_missedHeartbeats ++ ;
992
- }
993
- else
994
- {
995
- m_missedHeartbeats = 0 ;
996
- }
997
-
998
- // We check against 8 = 2 * 4 because we need to wait for at
999
- // least two complete heartbeat setting intervals before
1000
- // complaining, and we've set the socket timeout to a quarter
1001
- // of the heartbeat setting in setHeartbeat above.
1002
- if ( m_missedHeartbeats > 2 * 4 )
1003
- {
1004
- String description = String . Format ( "Heartbeat missing with heartbeat == {0} seconds" , m_heartbeat ) ;
1005
- var eose = new EndOfStreamException ( description ) ;
1006
- ESLog . Error ( description , eose ) ;
1007
- m_shutdownReport . Add ( new ShutdownReportEntry ( description , eose ) ) ;
1008
- HandleMainLoopException (
1009
- new ShutdownEventArgs ( ShutdownInitiator . Library , 0 , "End of stream" , eose ) ) ;
1010
- shouldTerminate = true ;
1011
- }
980
+ m_missedHeartbeats ++ ;
1012
981
}
1013
-
1014
- if ( shouldTerminate )
982
+ else
1015
983
{
1016
- TerminateMainloop ( ) ;
1017
- FinishClose ( ) ;
984
+ m_missedHeartbeats = 0 ;
1018
985
}
1019
- else if ( _heartbeatReadTimer != null )
986
+
987
+ // We check against 8 = 2 * 4 because we need to wait for at
988
+ // least two complete heartbeat setting intervals before
989
+ // complaining, and we've set the socket timeout to a quarter
990
+ // of the heartbeat setting in setHeartbeat above.
991
+ if ( m_missedHeartbeats > 2 * 4 )
1020
992
{
1021
- _heartbeatReadTimer . Change ( Heartbeat * 1000 , Timeout . Infinite ) ;
993
+ String description = String . Format ( "Heartbeat missing with heartbeat == {0} seconds" , m_heartbeat ) ;
994
+ var eose = new EndOfStreamException ( description ) ;
995
+ ESLog . Error ( description , eose ) ;
996
+ m_shutdownReport . Add ( new ShutdownReportEntry ( description , eose ) ) ;
997
+ HandleMainLoopException (
998
+ new ShutdownEventArgs ( ShutdownInitiator . Library , 0 , "End of stream" , eose ) ) ;
999
+ shouldTerminate = true ;
1022
1000
}
1023
1001
}
1024
- catch ( ObjectDisposedException )
1002
+
1003
+ if ( shouldTerminate )
1025
1004
{
1026
- // timer is already disposed,
1027
- // e.g. due to shutdown
1005
+ TerminateMainloop ( ) ;
1006
+ FinishClose ( ) ;
1028
1007
}
1029
- catch ( NullReferenceException )
1008
+ else if ( _heartbeatReadTimer != null )
1030
1009
{
1031
- // timer has already been disposed from a different thread after null check
1032
- // this event should be rare
1010
+ _heartbeatReadTimer . Change ( Heartbeat * 1000 , Timeout . Infinite ) ;
1033
1011
}
1034
1012
}
1013
+ catch ( ObjectDisposedException )
1014
+ {
1015
+ // timer is already disposed,
1016
+ // e.g. due to shutdown
1017
+ }
1018
+ catch ( NullReferenceException )
1019
+ {
1020
+ // timer has already been disposed from a different thread after null check
1021
+ // this event should be rare
1022
+ }
1035
1023
}
1036
1024
1037
1025
public void HeartbeatWriteTimerCallback ( object state )
1038
1026
{
1039
- lock ( _heartBeatWriteLock )
1027
+ if ( _heartbeatWriteTimer == null )
1040
1028
{
1041
- if ( m_hasDisposedHeartBeatWriteTimer )
1042
- {
1043
- return ;
1044
- }
1029
+ return ;
1045
1030
}
1046
1031
1047
1032
try
@@ -1062,51 +1047,17 @@ public void HeartbeatWriteTimerCallback(object state)
1062
1047
// peer unavailability. See rabbitmq/rabbitmq-dotnet-client#638 for details.
1063
1048
}
1064
1049
1065
- lock ( _heartBeatWriteLock )
1050
+ if ( m_closed == false )
1066
1051
{
1067
- if ( m_closed == false && _heartbeatWriteTimer != null )
1068
- {
1069
- _heartbeatWriteTimer . Change ( ( int ) m_heartbeatTimeSpan . TotalMilliseconds , Timeout . Infinite ) ;
1070
- }
1052
+ _heartbeatWriteTimer ? . Change ( ( int ) m_heartbeatTimeSpan . TotalMilliseconds , Timeout . Infinite ) ;
1071
1053
}
1072
1054
}
1073
1055
1074
1056
void MaybeStopHeartbeatTimers ( )
1075
1057
{
1076
- lock ( _heartBeatReadLock )
1077
- {
1078
- MaybeDisposeTimer ( ref _heartbeatReadTimer ) ;
1079
- m_hasDisposedHeartBeatReadTimer = true ;
1080
- }
1081
-
1082
- lock ( _heartBeatWriteLock )
1083
- {
1084
- MaybeDisposeTimer ( ref _heartbeatWriteTimer ) ;
1085
- m_hasDisposedHeartBeatWriteTimer = true ;
1086
- }
1087
- }
1088
-
1089
- private void MaybeDisposeTimer ( ref Timer timer )
1090
- {
1091
- // capture the timer to reduce chance of a null ref exception
1092
- var captured = timer ;
1093
- if ( captured != null )
1094
- {
1095
- try
1096
- {
1097
- captured . Change ( Timeout . Infinite , Timeout . Infinite ) ;
1098
- captured . Dispose ( ) ;
1099
- timer = null ;
1100
- }
1101
- catch ( ObjectDisposedException )
1102
- {
1103
- // we are shutting down, ignore
1104
- }
1105
- catch ( NullReferenceException )
1106
- {
1107
- // this should be very rare but could occur from a race condition
1108
- }
1109
- }
1058
+ NotifyHeartbeatListener ( ) ;
1059
+ _heartbeatReadTimer ? . Dispose ( ) ;
1060
+ _heartbeatWriteTimer ? . Dispose ( ) ;
1110
1061
}
1111
1062
1112
1063
///<remarks>
@@ -1231,9 +1182,8 @@ private void Dispose(bool disposing)
1231
1182
// dispose managed resources
1232
1183
try
1233
1184
{
1234
- _mainLoopTask . Wait ( ) ;
1235
- MaybeStopHeartbeatTimers ( ) ;
1236
1185
Abort ( ) ;
1186
+ _mainLoopTask . Wait ( ) ;
1237
1187
}
1238
1188
catch ( OperationInterruptedException )
1239
1189
{
0 commit comments