summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-01-29 13:15:19 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-01-29 13:15:19 (GMT)
commit2934262fd36c35843c01b96657047625ce2e3cf6 (patch)
tree6e23f70391742924251faa7bf82092532951411d /Lib/asyncio
parent54a231d5397bda24257f253eb1aaabf1b741a0b5 (diff)
downloadcpython-2934262fd36c35843c01b96657047625ce2e3cf6.zip
cpython-2934262fd36c35843c01b96657047625ce2e3cf6.tar.gz
cpython-2934262fd36c35843c01b96657047625ce2e3cf6.tar.bz2
asyncio: sync with Tulip
* Cleanup gather(): use cancelled() method instead of using private Future attribute * Fix _UnixReadPipeTransport and _UnixWritePipeTransport. Only start reading when connection_made() has been called. * Issue #23333: Fix BaseSelectorEventLoop._accept_connection(). Close the transport on error. In debug mode, log errors using call_exception_handler()
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/selector_events.py44
-rw-r--r--Lib/asyncio/tasks.py2
-rw-r--r--Lib/asyncio/unix_events.py17
3 files changed, 50 insertions, 13 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index 3195f62..9147832 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -22,6 +22,7 @@ from . import futures
from . import selectors
from . import transports
from . import sslproto
+from .coroutines import coroutine
from .log import logger
@@ -181,16 +182,47 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
else:
raise # The event loop will catch, log and ignore it.
else:
+ extra = {'peername': addr}
+ accept = self._accept_connection2(protocol_factory, conn, extra,
+ sslcontext, server)
+ self.create_task(accept)
+
+ @coroutine
+ def _accept_connection2(self, protocol_factory, conn, extra,
+ sslcontext=None, server=None):
+ protocol = None
+ transport = None
+ try:
protocol = protocol_factory()
+ waiter = futures.Future(loop=self)
if sslcontext:
- self._make_ssl_transport(
- conn, protocol, sslcontext,
- server_side=True, extra={'peername': addr}, server=server)
+ transport = self._make_ssl_transport(
+ conn, protocol, sslcontext, waiter=waiter,
+ server_side=True, extra=extra, server=server)
else:
- self._make_socket_transport(
- conn, protocol , extra={'peername': addr},
+ transport = self._make_socket_transport(
+ conn, protocol, waiter=waiter, extra=extra,
server=server)
- # It's now up to the protocol to handle the connection.
+
+ try:
+ yield from waiter
+ except:
+ transport.close()
+ raise
+
+ # It's now up to the protocol to handle the connection.
+ except Exception as exc:
+ if self.get_debug():
+ context = {
+ 'message': ('Error on transport creation '
+ 'for incoming connection'),
+ 'exception': exc,
+ }
+ if protocol is not None:
+ context['protocol'] = protocol
+ if transport is not None:
+ context['transport'] = transport
+ self.call_exception_handler(context)
def add_reader(self, fd, callback, *args):
"""Add a reader callback."""
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 63412a9..4f19a25 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -592,7 +592,7 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False):
fut.exception()
return
- if fut._state == futures._CANCELLED:
+ if fut.cancelled():
res = futures.CancelledError()
if not return_exceptions:
outer.set_exception(res)
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 67973f1..7e1265a 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -298,8 +298,10 @@ class _UnixReadPipeTransport(transports.ReadTransport):
_set_nonblocking(self._fileno)
self._protocol = protocol
self._closing = False
- self._loop.add_reader(self._fileno, self._read_ready)
self._loop.call_soon(self._protocol.connection_made, self)
+ # only start reading when connection_made() has been called
+ self._loop.call_soon(self._loop.add_reader,
+ self._fileno, self._read_ready)
if waiter is not None:
# only wake up the waiter when connection_made() has been called
self._loop.call_soon(waiter._set_result_unless_cancelled, None)
@@ -401,13 +403,16 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
self._conn_lost = 0
self._closing = False # Set when close() or write_eof() called.
- # On AIX, the reader trick only works for sockets.
- # On other platforms it works for pipes and sockets.
- # (Exception: OS X 10.4? Issue #19294.)
+ self._loop.call_soon(self._protocol.connection_made, self)
+
+ # On AIX, the reader trick (to be notified when the read end of the
+ # socket is closed) only works for sockets. On other platforms it
+ # works for pipes and sockets. (Exception: OS X 10.4? Issue #19294.)
if is_socket or not sys.platform.startswith("aix"):
- self._loop.add_reader(self._fileno, self._read_ready)
+ # only start reading when connection_made() has been called
+ self._loop.call_soon(self._loop.add_reader,
+ self._fileno, self._read_ready)
- self._loop.call_soon(self._protocol.connection_made, self)
if waiter is not None:
# only wake up the waiter when connection_made() has been called
self._loop.call_soon(waiter._set_result_unless_cancelled, None)