diff options
author | Antoine Pitrou <pitrou@free.fr> | 2017-10-19 19:46:40 (GMT) |
---|---|---|
committer | Yury Selivanov <yury@magic.io> | 2017-10-19 19:46:40 (GMT) |
commit | 525f40d231aba2c004619fc7a5207171ed65b0cb (patch) | |
tree | 60cda8363e0c027aa17a6bb4288d9436aa228829 /Lib/asyncio/selector_events.py | |
parent | ea2ef5d0ca869d4550820ed53bdf56013dbb9546 (diff) | |
download | cpython-525f40d231aba2c004619fc7a5207171ed65b0cb.zip cpython-525f40d231aba2c004619fc7a5207171ed65b0cb.tar.gz cpython-525f40d231aba2c004619fc7a5207171ed65b0cb.tar.bz2 |
bpo-31819: Add AbstractEventLoop.sock_recv_into() (#4051)
* bpo-31819: Add AbstractEventLoop.sock_recv_into()
* Add NEWS
* Add doc
Diffstat (limited to 'Lib/asyncio/selector_events.py')
-rw-r--r-- | Lib/asyncio/selector_events.py | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 4b40356..7143ca2 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -386,6 +386,41 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): else: fut.set_result(data) + def sock_recv_into(self, sock, buf): + """Receive data from the socket. + + The received data is written into *buf* (a writable buffer). + The return value is the number of bytes written. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") + fut = self.create_future() + self._sock_recv_into(fut, False, sock, buf) + return fut + + def _sock_recv_into(self, fut, registered, sock, buf): + # _sock_recv_into() can add itself as an I/O callback if the operation + # can't be done immediately. Don't use it directly, call sock_recv_into(). + fd = sock.fileno() + if registered: + # Remove the callback early. It should be rare that the + # selector says the fd is ready but the call still returns + # EAGAIN, and I am willing to take a hit in that case in + # order to simplify the common case. + self.remove_reader(fd) + if fut.cancelled(): + return + try: + nbytes = sock.recv_into(buf) + except (BlockingIOError, InterruptedError): + self.add_reader(fd, self._sock_recv_into, fut, True, sock, buf) + except Exception as exc: + fut.set_exception(exc) + else: + fut.set_result(nbytes) + def sock_sendall(self, sock, data): """Send data to the socket. |