diff options
author | Damien George <damien@micropython.org> | 2021-06-25 16:53:20 +1000 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2021-06-26 22:30:22 +1000 |
commit | 7ec95c2768793c28351d13a9c471991bb2d6dcff (patch) | |
tree | cc65bc817cca1c6c9455316c1a588068d26e5b4b /extmod/uasyncio | |
parent | cbc9a591a437177ac978302c16b56dd6cb46104f (diff) |
extmod/uasyncio: Get addr and bind server socket before creating task.
Currently when using uasyncio.start_server() the socket configuration is
done inside a uasyncio.create_task() background function. If the address
and port are already in use however this throws an OSError which cannot be
cleanly caught behind the create_task().
This commit moves the getaddrinfo and socket binding to the start_server()
function, and only creates the task if that succeeds. This means that any
OSError from the initial socket configuration is propagated directly up the
call stack, compatible with CPython behaviour.
See #7444.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'extmod/uasyncio')
-rw-r--r-- | extmod/uasyncio/stream.py | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/extmod/uasyncio/stream.py b/extmod/uasyncio/stream.py index 3a68881da..8de2d2599 100644 --- a/extmod/uasyncio/stream.py +++ b/extmod/uasyncio/stream.py @@ -107,15 +107,7 @@ class Server: async def wait_closed(self): await self.task - async def _serve(self, cb, host, port, backlog): - import usocket as socket - - ai = socket.getaddrinfo(host, port)[0] # TODO this is blocking! - s = socket.socket() - s.setblocking(False) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind(ai[-1]) - s.listen(backlog) + async def _serve(self, s, cb): # Accept incoming connections while True: try: @@ -137,9 +129,20 @@ class Server: # Helper function to start a TCP stream server, running as a new task # TODO could use an accept-callback on socket read activity instead of creating a task async def start_server(cb, host, port, backlog=5): - s = Server() - s.task = core.create_task(s._serve(cb, host, port, backlog)) - return s + import usocket as socket + + # Create and bind server socket. + host = socket.getaddrinfo(host, port)[0] # TODO this is blocking! + s = socket.socket() + s.setblocking(False) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind(host[-1]) + s.listen(backlog) + + # Create and return server object and task. + srv = Server() + srv.task = core.create_task(srv._serve(s, cb)) + return srv ################################################################################ |