extmod/modlwip: Properly handle non-blocking and timeout on UDP recv.
Fixes UDP non-blocking recv so it returns EAGAIN instead of ETIMEDOUT. Timeout waiting for incoming data is also improved by replacing 100ms delay with poll_sockets(), as is done in other parts of this module. Fixes issue #5759.
This commit is contained in:
parent
00267aae0b
commit
8f0778b209
@ -598,21 +598,20 @@ STATIC mp_uint_t lwip_raw_udp_send(lwip_socket_obj_t *socket, const byte *buf, m
|
|||||||
STATIC mp_uint_t lwip_raw_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
|
STATIC mp_uint_t lwip_raw_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
|
||||||
|
|
||||||
if (socket->incoming.pbuf == NULL) {
|
if (socket->incoming.pbuf == NULL) {
|
||||||
if (socket->timeout != -1) {
|
if (socket->timeout == 0) {
|
||||||
for (mp_uint_t retries = socket->timeout / 100; retries--;) {
|
// Non-blocking socket.
|
||||||
mp_hal_delay_ms(100);
|
*_errno = MP_EAGAIN;
|
||||||
if (socket->incoming.pbuf != NULL) {
|
return -1;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
// Wait for data to arrive on UDP socket.
|
||||||
if (socket->incoming.pbuf == NULL) {
|
mp_uint_t start = mp_hal_ticks_ms();
|
||||||
|
while (socket->incoming.pbuf == NULL) {
|
||||||
|
if (socket->timeout != -1 && mp_hal_ticks_ms() - start > socket->timeout) {
|
||||||
*_errno = MP_ETIMEDOUT;
|
*_errno = MP_ETIMEDOUT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
poll_sockets();
|
||||||
while (socket->incoming.pbuf == NULL) {
|
|
||||||
poll_sockets();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
tests/extmod/usocket_udp_nonblock.py
Normal file
20
tests/extmod/usocket_udp_nonblock.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# test non-blocking UDP sockets
|
||||||
|
|
||||||
|
try:
|
||||||
|
import usocket as socket, uerrno as errno
|
||||||
|
except ImportError:
|
||||||
|
try:
|
||||||
|
import socket, errno
|
||||||
|
except ImportError:
|
||||||
|
print("SKIP")
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
|
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.bind(socket.getaddrinfo('127.0.0.1', 8000)[0][-1])
|
||||||
|
s.settimeout(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
s.recv(1)
|
||||||
|
except OSError as er:
|
||||||
|
print('EAGAIN:', er.args[0] == errno.EAGAIN)
|
Loading…
x
Reference in New Issue
Block a user