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 ;
@@ -108,10 +109,6 @@ public class Connection : IConnection
108
109
private Timer _heartbeatReadTimer ;
109
110
private AutoResetEvent m_heartbeatRead = new AutoResetEvent ( false ) ;
110
111
111
- private readonly object _heartBeatReadLock = new object ( ) ;
112
- private readonly object _heartBeatWriteLock = new object ( ) ;
113
- private bool m_hasDisposedHeartBeatReadTimer ;
114
- private bool m_hasDisposedHeartBeatWriteTimer ;
115
112
private Task _mainLoopTask ;
116
113
117
114
#if CORECLR
@@ -543,8 +540,6 @@ public void EnsureIsOpen()
543
540
// Only call at the end of the Mainloop or HeartbeatLoop
544
541
public void FinishClose ( )
545
542
{
546
- // Notify hearbeat loops that they can leave
547
- m_heartbeatRead . Set ( ) ;
548
543
m_closed = true ;
549
544
MaybeStopHeartbeatTimers ( ) ;
550
545
@@ -1014,8 +1009,6 @@ public void MaybeStartHeartbeatTimers()
1014
1009
{
1015
1010
if ( Heartbeat != 0 )
1016
1011
{
1017
- m_hasDisposedHeartBeatReadTimer = false ;
1018
- m_hasDisposedHeartBeatWriteTimer = false ;
1019
1012
#if NETFX_CORE
1020
1013
lock ( _heartBeatWriteLock )
1021
1014
{
@@ -1030,17 +1023,15 @@ public void MaybeStartHeartbeatTimers()
1030
1023
_heartbeatReadTimer . Change ( 300 , Timeout . Infinite ) ;
1031
1024
}
1032
1025
#else
1033
- lock ( _heartBeatWriteLock )
1026
+ if ( _heartbeatWriteTimer == null )
1034
1027
{
1035
1028
_heartbeatWriteTimer = new Timer ( HeartbeatWriteTimerCallback , null , Timeout . Infinite , Timeout . Infinite ) ;
1036
-
1037
1029
_heartbeatWriteTimer . Change ( 200 , Timeout . Infinite ) ;
1038
1030
}
1039
1031
1040
- lock ( _heartBeatReadLock )
1032
+ if ( _heartbeatReadTimer == null )
1041
1033
{
1042
1034
_heartbeatReadTimer = new Timer ( HeartbeatReadTimerCallback , null , Timeout . Infinite , Timeout . Infinite ) ;
1043
-
1044
1035
_heartbeatReadTimer . Change ( 300 , Timeout . Infinite ) ;
1045
1036
}
1046
1037
#endif
@@ -1054,75 +1045,69 @@ public void StartMainLoop(bool useBackgroundThread)
1054
1045
1055
1046
public void HeartbeatReadTimerCallback ( object state )
1056
1047
{
1057
- lock ( _heartBeatReadLock )
1048
+ if ( _heartbeatReadTimer == null )
1058
1049
{
1059
- if ( m_hasDisposedHeartBeatReadTimer )
1060
- {
1061
- return ;
1062
- }
1050
+ return ;
1051
+ }
1063
1052
1064
- bool shouldTerminate = false ;
1053
+ bool shouldTerminate = false ;
1065
1054
1066
- try
1055
+ try
1056
+ {
1057
+ if ( ! m_closed )
1067
1058
{
1068
- if ( ! m_closed )
1059
+ if ( ! m_heartbeatRead . WaitOne ( 0 ) )
1069
1060
{
1070
- if ( ! m_heartbeatRead . WaitOne ( 0 ) )
1071
- {
1072
- m_missedHeartbeats ++ ;
1073
- }
1074
- else
1075
- {
1076
- m_missedHeartbeats = 0 ;
1077
- }
1078
-
1079
- // We check against 8 = 2 * 4 because we need to wait for at
1080
- // least two complete heartbeat setting intervals before
1081
- // complaining, and we've set the socket timeout to a quarter
1082
- // of the heartbeat setting in setHeartbeat above.
1083
- if ( m_missedHeartbeats > 2 * 4 )
1084
- {
1085
- String description = String . Format ( "Heartbeat missing with heartbeat == {0} seconds" , m_heartbeat ) ;
1086
- var eose = new EndOfStreamException ( description ) ;
1087
- ESLog . Error ( description , eose ) ;
1088
- m_shutdownReport . Add ( new ShutdownReportEntry ( description , eose ) ) ;
1089
- HandleMainLoopException (
1090
- new ShutdownEventArgs ( ShutdownInitiator . Library , 0 , "End of stream" , eose ) ) ;
1091
- shouldTerminate = true ;
1092
- }
1061
+ m_missedHeartbeats ++ ;
1093
1062
}
1094
-
1095
- if ( shouldTerminate )
1063
+ else
1096
1064
{
1097
- TerminateMainloop ( ) ;
1098
- FinishClose ( ) ;
1065
+ m_missedHeartbeats = 0 ;
1099
1066
}
1100
- else if ( _heartbeatReadTimer != null )
1067
+
1068
+ // We check against 8 = 2 * 4 because we need to wait for at
1069
+ // least two complete heartbeat setting intervals before
1070
+ // complaining, and we've set the socket timeout to a quarter
1071
+ // of the heartbeat setting in setHeartbeat above.
1072
+ if ( m_missedHeartbeats > 2 * 4 )
1101
1073
{
1102
- _heartbeatReadTimer . Change ( Heartbeat * 1000 , Timeout . Infinite ) ;
1074
+ String description = String . Format ( "Heartbeat missing with heartbeat == {0} seconds" , m_heartbeat ) ;
1075
+ var eose = new EndOfStreamException ( description ) ;
1076
+ ESLog . Error ( description , eose ) ;
1077
+ m_shutdownReport . Add ( new ShutdownReportEntry ( description , eose ) ) ;
1078
+ HandleMainLoopException (
1079
+ new ShutdownEventArgs ( ShutdownInitiator . Library , 0 , "End of stream" , eose ) ) ;
1080
+ shouldTerminate = true ;
1103
1081
}
1104
1082
}
1105
- catch ( ObjectDisposedException )
1083
+
1084
+ if ( shouldTerminate )
1106
1085
{
1107
- // timer is already disposed,
1108
- // e.g. due to shutdown
1086
+ TerminateMainloop ( ) ;
1087
+ FinishClose ( ) ;
1109
1088
}
1110
- catch ( NullReferenceException )
1089
+ else if ( _heartbeatReadTimer != null )
1111
1090
{
1112
- // timer has already been disposed from a different thread after null check
1113
- // this event should be rare
1091
+ _heartbeatReadTimer . Change ( Heartbeat * 1000 , Timeout . Infinite ) ;
1114
1092
}
1115
1093
}
1094
+ catch ( ObjectDisposedException )
1095
+ {
1096
+ // timer is already disposed,
1097
+ // e.g. due to shutdown
1098
+ }
1099
+ catch ( NullReferenceException )
1100
+ {
1101
+ // timer has already been disposed from a different thread after null check
1102
+ // this event should be rare
1103
+ }
1116
1104
}
1117
1105
1118
1106
public void HeartbeatWriteTimerCallback ( object state )
1119
1107
{
1120
- lock ( _heartBeatWriteLock )
1108
+ if ( _heartbeatWriteTimer == null )
1121
1109
{
1122
- if ( m_hasDisposedHeartBeatWriteTimer )
1123
- {
1124
- return ;
1125
- }
1110
+ return ;
1126
1111
}
1127
1112
1128
1113
try
@@ -1143,51 +1128,17 @@ public void HeartbeatWriteTimerCallback(object state)
1143
1128
// peer unavailability. See rabbitmq/rabbitmq-dotnet-client#638 for details.
1144
1129
}
1145
1130
1146
- lock ( _heartBeatWriteLock )
1131
+ if ( m_closed == false )
1147
1132
{
1148
- if ( m_closed == false && _heartbeatWriteTimer != null )
1149
- {
1150
- _heartbeatWriteTimer . Change ( ( int ) m_heartbeatTimeSpan . TotalMilliseconds , Timeout . Infinite ) ;
1151
- }
1133
+ _heartbeatWriteTimer ? . Change ( ( int ) m_heartbeatTimeSpan . TotalMilliseconds , Timeout . Infinite ) ;
1152
1134
}
1153
1135
}
1154
1136
1155
1137
void MaybeStopHeartbeatTimers ( )
1156
1138
{
1157
- lock ( _heartBeatReadLock )
1158
- {
1159
- MaybeDisposeTimer ( ref _heartbeatReadTimer ) ;
1160
- m_hasDisposedHeartBeatReadTimer = true ;
1161
- }
1162
-
1163
- lock ( _heartBeatWriteLock )
1164
- {
1165
- MaybeDisposeTimer ( ref _heartbeatWriteTimer ) ;
1166
- m_hasDisposedHeartBeatWriteTimer = true ;
1167
- }
1168
- }
1169
-
1170
- private void MaybeDisposeTimer ( ref Timer timer )
1171
- {
1172
- // capture the timer to reduce chance of a null ref exception
1173
- var captured = timer ;
1174
- if ( captured != null )
1175
- {
1176
- try
1177
- {
1178
- captured . Change ( Timeout . Infinite , Timeout . Infinite ) ;
1179
- captured . Dispose ( ) ;
1180
- timer = null ;
1181
- }
1182
- catch ( ObjectDisposedException )
1183
- {
1184
- // we are shutting down, ignore
1185
- }
1186
- catch ( NullReferenceException )
1187
- {
1188
- // this should be very rare but could occur from a race condition
1189
- }
1190
- }
1139
+ NotifyHeartbeatListener ( ) ;
1140
+ _heartbeatReadTimer ? . Dispose ( ) ;
1141
+ _heartbeatWriteTimer ? . Dispose ( ) ;
1191
1142
}
1192
1143
1193
1144
///<remarks>
@@ -1312,9 +1263,8 @@ private void Dispose(bool disposing)
1312
1263
// dispose managed resources
1313
1264
try
1314
1265
{
1315
- _mainLoopTask . Wait ( ) ;
1316
- MaybeStopHeartbeatTimers ( ) ;
1317
1266
Abort ( ) ;
1267
+ _mainLoopTask . Wait ( ) ;
1318
1268
}
1319
1269
catch ( OperationInterruptedException )
1320
1270
{
0 commit comments