From cba7e2b0d3a0e0a1205b58a334a1dd3e3346e8b7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 2 Nov 2017 17:06:01 +0100 Subject: [PATCH] asyncio: Fix _set_nodelay() for non-blocking socket bpo-27456. --- Lib/asyncio/selector_events.py | 2 +- Lib/test/test_asyncio/test_selector_events.py | 27 +++++++++++++++++++ .../2017-11-02-17-08-02.bpo-27456.wWa1LV.rst | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2017-11-02-17-08-02.bpo-27456.wWa1LV.rst diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 7143ca2660afaa..28e0bd9c94c00a 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -42,7 +42,7 @@ def _test_selector_event(selector, fd, event): if hasattr(socket, 'TCP_NODELAY'): def _set_nodelay(sock): if (sock.family in {socket.AF_INET, socket.AF_INET6} and - sock.type == socket.SOCK_STREAM and + base_events._is_stream_socket(sock) and sock.proto == socket.IPPROTO_TCP): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) else: diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index c50b3e49565c92..98c28afde16b45 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -17,6 +17,7 @@ from asyncio.selector_events import _SelectorSslTransport from asyncio.selector_events import _SelectorSocketTransport from asyncio.selector_events import _SelectorDatagramTransport +from asyncio.selector_events import _set_nodelay MOCK_ANY = mock.ANY @@ -1787,5 +1788,31 @@ def test_fatal_error_connected(self, m_exc): 'Fatal error on transport\nprotocol:.*\ntransport:.*'), exc_info=(ConnectionRefusedError, MOCK_ANY, MOCK_ANY)) + +class TestSelectorUtils(test_utils.TestCase): + def check_set_nodelay(self, sock): + opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY) + self.assertFalse(opt) + + _set_nodelay(sock) + + opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY) + self.assertTrue(opt) + + @unittest.skipUnless(hasattr(socket, 'TCP_NODELAY'), + 'need socket.TCP_NODELAY') + def test_set_nodelay(self): + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + self.check_set_nodelay(sock) + + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + sock.setblocking(False) + self.check_set_nodelay(sock) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2017-11-02-17-08-02.bpo-27456.wWa1LV.rst b/Misc/NEWS.d/next/Library/2017-11-02-17-08-02.bpo-27456.wWa1LV.rst new file mode 100644 index 00000000000000..f180b19980fcdf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-02-17-08-02.bpo-27456.wWa1LV.rst @@ -0,0 +1 @@ +Fix asyncio: Set also the TCP_NODELAY flag on non-blocking sockets.