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.
This commit is contained in:
Damien George 2019-01-10 15:46:44 +11:00
parent efe0569c26
commit f350b640a0

View File

@ -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;
}