Browse Source

esp32/modsocket: For socket read only release GIL if socket would block.

If there are many short reads to a socket in a row (eg by readline) then
releasing and acquiring the GIL each time will give very poor throughput.
So first poll the socket to see if it has data, and if it does then don't
release the GIL.
pull/4486/head
Damien George 6 years ago
parent
commit
f350b640a0
  1. 19
      ports/esp32/modsocket.c

19
ports/esp32/modsocket.c

@ -375,9 +375,24 @@ STATIC mp_uint_t _socket_read_data(mp_obj_t self_in, void *buf, size_t size,
// XXX Would be nicer to use RTC to handle timeouts
for (int i = 0; i <= sock->retries; ++i) {
MP_THREAD_GIL_EXIT();
// Poll the socket to see if it has waiting data and only release the GIL if it doesn't.
// This ensures higher performance in the case of many small reads, eg for readline.
bool release_gil;
{
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sock->fd, &rfds);
struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
int r = select(sock->fd + 1, &rfds, NULL, NULL, &timeout);
release_gil = r != 1;
}
if (release_gil) {
MP_THREAD_GIL_EXIT();
}
int r = lwip_recvfrom_r(sock->fd, buf, size, 0, from, from_len);
MP_THREAD_GIL_ENTER();
if (release_gil) {
MP_THREAD_GIL_ENTER();
}
if (r == 0) {
sock->peer_closed = true;
}

Loading…
Cancel
Save