Skip to content

Commit fa2e95d

Browse files
authored
Merge pull request #188 from FoamyGuy/pr_171_merge_main
Pr 171 merge main
2 parents df380eb + 8111064 commit fa2e95d

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,14 @@ def recv_into(self, buffer: bytearray, nbytes: int = 0, flags: int = 0) -> int:
595595
self._buffer = self._buffer[bytes_to_read:]
596596
# explicitly recheck num_to_read to avoid extra checks
597597
continue
598-
598+
# We need to read the socket status here before seeing if any bytes are available.
599+
# Otherwise, we have a bad race condition in the if/elif/... logic below
600+
# that can cause recv_into to fail when the other side closes the connection after
601+
# sending bytes. The problem is that initially we can have num_avail=0 while the
602+
# socket state is not in CLOSED or CLOSED_WAIT. Then after the if but before the elif
603+
# that checks the socket state, bytes arrive and the other end closes the connection.
604+
# So now bytes are available but we see the CLOSED/CLOSED_WAIT state and ignore them.
605+
status_before_getting_available = self._status
599606
num_avail = self._available()
600607
if num_avail > 0:
601608
last_read_time = ticks_ms()
@@ -610,7 +617,9 @@ def recv_into(self, buffer: bytearray, nbytes: int = 0, flags: int = 0) -> int:
610617
elif num_read > 0:
611618
# We got a message, but there are no more bytes to read, so we can stop.
612619
break
613-
elif self._status in {
620+
# See note where we set status_before_getting_available for why we can't just check
621+
# _status here
622+
elif status_before_getting_available in {
614623
wiznet5k.adafruit_wiznet5k.SNSR_SOCK_CLOSED,
615624
wiznet5k.adafruit_wiznet5k.SNSR_SOCK_CLOSE_WAIT,
616625
}:

0 commit comments

Comments
 (0)