Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Using transport's socket with low level add_reader/add_writer #372

Closed
@1st1

Description

@1st1

Turns out people use transports' sockets with add_reader / add_writer low level APIs. I've discovered this while debugging a crash of a webapp deployed with uvloop. The reason of that crash is how aiohttp implements sendfile: they use transport.get_extra_info('socket') to get the underlying socket, and then they use loop.add_writer and loop.remove_writer on that socket.

The crash in uvloop is caused by how file descriptors are stored internally by libuv. I'll make a workaround for that by using os.dup() to return a duplicate socket from transport.get_extra_info('socket').

However, I think we should do this in asyncio too. The thing is that when you use add_writer and remove_writer on the transport's socket, you're messing with the internal state of the transport. For instance, a transport might be in the middle of writing data, and calling remove_writer will cause the whole program to hang.

I see two options:

  1. We always return duplicate sockets from transport.get_extra_info(), hiding the actual socket that transport is attached to.
  2. We find a way to raise an exception if add|remove_witer|reader is used on a transport's socket.

I'm more inclined to do the 1.

/cc @asvetlov

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions