@@ -1205,22 +1205,27 @@ def return_socket(self, sock_info, publish_checkin=True):
1205
1205
else :
1206
1206
if self .closed :
1207
1207
sock_info .close_socket (ConnectionClosedReason .POOL_CLOSED )
1208
- elif sock_info .generation != self .generation :
1209
- sock_info .close_socket (ConnectionClosedReason .STALE )
1210
1208
elif not sock_info .closed :
1211
- sock_info .update_last_checkin_time ()
1212
- sock_info .update_is_writable (self .is_writable )
1213
1209
with self .lock :
1214
- self .sockets .appendleft (sock_info )
1210
+ # Hold the lock to ensure this section does not race with
1211
+ # Pool.reset().
1212
+ if sock_info .generation != self .generation :
1213
+ sock_info .close_socket (ConnectionClosedReason .STALE )
1214
+ else :
1215
+ sock_info .update_last_checkin_time ()
1216
+ sock_info .update_is_writable (self .is_writable )
1217
+ self .sockets .appendleft (sock_info )
1215
1218
1216
1219
self ._socket_semaphore .release ()
1217
1220
with self .lock :
1218
1221
self .active_sockets -= 1
1219
1222
1220
1223
def _perished (self , sock_info ):
1221
- """This side-effecty function checks if this socket has been idle for
1224
+ """Return True and close the connection if it is "perished".
1225
+
1226
+ This side-effecty function checks if this socket has been idle for
1222
1227
for longer than the max idle time, or if the socket has been closed by
1223
- some external network error.
1228
+ some external network error, or if the socket's generation is outdated .
1224
1229
1225
1230
Checking sockets lets us avoid seeing *some*
1226
1231
:class:`~pymongo.errors.AutoReconnect` exceptions on server
@@ -1243,6 +1248,10 @@ def _perished(self, sock_info):
1243
1248
sock_info .close_socket (ConnectionClosedReason .ERROR )
1244
1249
return True
1245
1250
1251
+ if sock_info .generation != self .generation :
1252
+ sock_info .close_socket (ConnectionClosedReason .STALE )
1253
+ return True
1254
+
1246
1255
return False
1247
1256
1248
1257
def _raise_wait_queue_timeout (self ):
0 commit comments