← index #4290Issue #3005
Related · medium · value 0.135
QUERY · ISSUE

uselect: poll instance produces unexpected results under fault conditions

openby peterhinchopened 2018-11-03updated 2019-10-31
extmod

Context: uasyncio StreamReader and StreamWriter objects hang indefinitely under fault conditions.

Under fault conditions uasyncio expects to receive POLLERR or POLLHUP conditions from the poll instance. In my testing this never occurs.

Testing was of client connections. Socket type was SOCK_STREAM. Two fault conditions were tested:

  1. Server outage.
  2. Socket closed by another coroutine.

Testing was performed with a server running under the Unix build. Clients were tested on:

  1. Unix build (on same machine as server).
  2. ESP8266.
  3. ESP32.

Results were as follows. Numbers represent the event no. received from the poll instance. "No trigger" means that the poll instance produced no response after the fault. On all platforms where the client was reading, a server outage produced a POLLIN (1) response. On all but ESP32 this repeated indefinitely causing the client endlessly to read empty bytes objects.

Numbers are base 10. Mode refers to the client mode. Expected refers to uasyncio.

Mode Platform Outage Closure Expected
Read Unix 1 32 9 or 17
Read ESP8266 1 No trigger 9 or 17
Read ESP32 1 (once) No trigger 9 or 17
Write Unix OSError 32 12 or 20
Write ESP8266 OSError No trigger 12 or 20
Write ESP832 OSError No trigger 12 or 20

1 == POLLIN
4 == POLLOUT
9 == (POLLIN & POLLERR)
17 == (POLLIN & POLLHUP)
12 == (POLLOUT & POLLERR)
20 == (POLLOUT & POLLHUP)
32 == Search me.

Test scripts may be found here:
Server - can run in read or write mode
Read client
Write client

CANDIDATE · ISSUE

uasyncio stream reader/writer: unexpected behaviour with UART

closedby peterhinchopened 2017-04-06updated 2017-04-07

Testing done on Pyboard V1.1. The sender coroutine iterates every 2 seconds but no output appears on pin X1:

import uasyncio as asyncio
from pyb import UART
uart = UART(4, 9600)

async def sender():
    swriter = asyncio.StreamWriter(uart, {})
    while True:
        swriter.awrite('Hello uart\n')
        await asyncio.sleep(2)
        print('wrote')

loop = asyncio.get_event_loop()
loop.create_task(sender())
loop.run_forever()

The next script produces output on X1 as expected until a loopback is applied (link X1 and X2). At this point the UART sends data continuously. The data is read correctly, but the call to

await asyncio.sleep(2) no longer behaves as expected.

import uasyncio as asyncio
from pyb import UART
uart = UART(4, 9600)

async def sender():
    while True:
        uart.write('Hello uart\n')
        await asyncio.sleep(2)
        print('Wrote')

async def receiver():
    sreader = asyncio.StreamReader(uart)
    while True:
        res = await sreader.readline()
        print('Recieved', res)

loop = asyncio.get_event_loop()
loop.create_task(sender())
loop.create_task(receiver())
loop.run_forever()

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied