Adding a low level wait for file descriptor

I had to integrate using asyncio a blocking library that uses sockets.

Typical use case:

async def handler(fd):
    loop = asyncio.get_running_loop()
    while True:
        await loop.wait_readable(fd)
        x = blocking_read_in_library()
        await long_processing(x)

I ended up using the loop.add_reader and loop.remove_reader functions, which is the only approach that seems to work with file descriptors. It’s a bit more error prone but works well. I don’t want to have repeated call to the blocking read if more data is available as anyway the long_processing happens in the background.

I believe that we could add these two functions instead:

async def wait_readable(loop, fd):
    event = asyncio.Event()
    loop.add_reader(fd, lambda: event.set())

    try:
        await event.wait()

    finally:
        loop.remove_reader(fd)

The function wait_writable could be implemented similarly. These are very simple functions to implement (maybe they shouldn’t be in stdlib) but I felt they could be useful for others.