aboutsummaryrefslogtreecommitdiff
path: root/extmod/uasyncio
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2021-06-25 16:53:20 +1000
committerDamien George <damien@micropython.org>2021-06-26 22:30:22 +1000
commit7ec95c2768793c28351d13a9c471991bb2d6dcff (patch)
treecc65bc817cca1c6c9455316c1a588068d26e5b4b /extmod/uasyncio
parentcbc9a591a437177ac978302c16b56dd6cb46104f (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.py27
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
################################################################################