non-blocking socket blocks and raises EAGAIN
from https://github.com/pfalcon/micropython/issues/30
Problem: a non-blocking socket seems to block and raises EAGAIN (was EWOULDBLOCK some time ago)
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import socket as _socket
=== ai = _socket.getaddrinfo("127.0.0.1", 85, 0, _socket.SOCK_STREAM)
=== ai = ai[0]
=== s = _socket.socket(ai[0], ai[1], ai[2])
=== s.setblocking(False)
=== s.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1)
=== s.bind(ai[-1])
=== s.listen(0)
===
>>> s2, client_addr = s.accept()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 11] EAGAIN
This problem only appears, when AP mode is disabled. Connecting to a WiFi does not help.
See https://github.com/pfalcon/micropython/issues/30#issuecomment-497322149
Catching EAGAIN works but this only circumvents that bug...
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import socket as _socket
=== ai = _socket.getaddrinfo("127.0.0.1", 85, 0, _socket.SOCK_STREAM)
=== ai = ai[0]
=== s = _socket.socket(ai[0], ai[1], ai[2])
=== s.setblocking(False)
=== s.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1)
=== s.bind(ai[-1])
=== s.listen(0)
===
>>> try:
>>> s2, client_addr = s.accept()
>>> except OSError as e:
>>> if e.args[0] == uerrno.EAGAIN:
>>> continue
>>>
extmod/modussl_axtls: socket_read: Handle EAGAIN.
If SSL_EAGAIN is returned (which is a feature of MicroPython's axTLS fork),
return EAGAIN.
Original axTLS returns SSL_OK both when there's no data to return to user
yet and when the underlying stream returns EAGAIN. That's not distinctive
enough, for example, original module code works well for blocking stream,
but will infinite-loop for non-blocking socket with EAGAIN. But if we fix
non-blocking case, blocking calls to .read() will return few None's initially
(while axTLS progresses thru handshake).
Using SSL_EAGAIN allows to fix non-blocking case without regressing the
blocking one.
Note that this only handles case of non-blocking reads of application data.
Initial handshake and writes still don't support non-blocking mode and must
be done in the blocking way.