summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/selector_events.py
diff options
context:
space:
mode:
authorAntoine Pitrou <pitrou@free.fr>2017-10-19 19:46:40 (GMT)
committerYury Selivanov <yury@magic.io>2017-10-19 19:46:40 (GMT)
commit525f40d231aba2c004619fc7a5207171ed65b0cb (patch)
tree60cda8363e0c027aa17a6bb4288d9436aa228829 /Lib/asyncio/selector_events.py
parentea2ef5d0ca869d4550820ed53bdf56013dbb9546 (diff)
downloadcpython-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.py35
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.