Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-91166: zero copy SelectorSocketTransport transport implementation #31871

Merged
merged 23 commits into from
Dec 24, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
39b538f
zero copy transport implementation
kumaraditya303 Mar 14, 2022
abd2dc3
WIP sendmsg
kumaraditya303 Mar 15, 2022
669b661
writelines implementation
kumaraditya303 Mar 15, 2022
0692952
use sysconf
kumaraditya303 Mar 15, 2022
2725334
fix tests
kumaraditya303 Mar 15, 2022
bed096d
skip test if sendmsg does not exists
kumaraditya303 Oct 24, 2022
f090e8d
📜🤖 Added by blurb_it.
blurb-it[bot] Oct 24, 2022
d6c77cd
fix check on other platforms
kumaraditya303 Oct 24, 2022
f2ee404
rename some vars
kumaraditya303 Nov 28, 2022
effab03
_HAVE_SENDMSG -> _HAS_SENDMSG
kumaraditya303 Nov 28, 2022
e1e4362
fix tests
kumaraditya303 Nov 28, 2022
bdb1bda
fix tests
kumaraditya303 Nov 28, 2022
d1fae6c
fix writelines and add comments
kumaraditya303 Nov 28, 2022
cd45016
optimize calling
kumaraditya303 Nov 28, 2022
5b962f5
use send if sendmsg does not exists in writelines
kumaraditya303 Nov 28, 2022
85d6909
Merge branch 'main' into asyncio-zero-copy
kumaraditya303 Nov 28, 2022
152b748
Update Lib/asyncio/selector_events.py
kumaraditya303 Dec 2, 2022
2c62bcb
more tests
kumaraditya303 Dec 13, 2022
9b92cff
check fatal error
kumaraditya303 Dec 13, 2022
7e05c2c
Merge branch 'main' into asyncio-zero-copy
kumaraditya303 Dec 13, 2022
97de955
Merge branch 'asyncio-zero-copy' of https://github.com/kumaraditya303…
kumaraditya303 Dec 13, 2022
57b1ba0
Merge branch 'main' of https://github.com/python/cpython into asyncio…
kumaraditya303 Dec 22, 2022
2ca3571
code review
kumaraditya303 Dec 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Lib/asyncio/selector_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,6 @@ def write(self, data):
raise RuntimeError('unable to write; sendfile is in progress')
if not data:
return
data = memoryview(data)

if self._conn_lost:
if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES:
Expand All @@ -1078,7 +1077,7 @@ def write(self, data):
self._fatal_error(exc, 'Fatal write error on socket transport')
return
else:
data = data[n:]
data = memoryview(data)[n:]
if not data:
return
# Not all was written; register write handler.
Expand Down
36 changes: 35 additions & 1 deletion Lib/test/test_asyncio/test_selector_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -766,14 +766,48 @@ def test_write_sendmsg_partial(self):
data = memoryview(b'data')
self.sock.sendmsg = mock.Mock()
# Sent partial data
self.sock.sendmsg.return_value = len(data) // 2
self.sock.sendmsg.return_value = 2

transport = self.socket_transport(sendmsg=True)
transport._buffer.append(data)
self.loop._add_writer(7, transport._write_ready)
transport._write_ready()
self.assertTrue(self.sock.sendmsg.called)
self.assertTrue(self.loop.writers)
self.assertEqual(list_to_buffer([b'ta']), transport._buffer)

@unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg')
def test_write_sendmsg_half_buffer(self):
data = [memoryview(b'data1'), memoryview(b'data2')]
self.sock.sendmsg = mock.Mock()
# Sent partial data
self.sock.sendmsg.return_value = 2

transport = self.socket_transport(sendmsg=True)
transport._buffer.extend(data)
self.loop._add_writer(7, transport._write_ready)
transport._write_ready()
kumaraditya303 marked this conversation as resolved.
Show resolved Hide resolved
self.assertTrue(self.sock.sendmsg.called)
self.assertTrue(self.loop.writers)
self.assertEqual(list_to_buffer([b'ta1', b'data2']), transport._buffer)
kumaraditya303 marked this conversation as resolved.
Show resolved Hide resolved

@unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg')
def test_write_sendmsg_OSError(self):
data = memoryview(b'data')
self.sock.sendmsg = mock.Mock()
err = self.sock.sendmsg.side_effect = OSError()

transport = self.socket_transport(sendmsg=True)
transport._fatal_error = mock.Mock()
transport._buffer.extend(data)
self.loop._add_writer(7, transport._write_ready)
kumaraditya303 marked this conversation as resolved.
Show resolved Hide resolved
transport._write_ready()
kumaraditya303 marked this conversation as resolved.
Show resolved Hide resolved
self.assertTrue(self.sock.sendmsg.called)
self.assertFalse(self.loop.writers)
self.assertEqual(list_to_buffer([]), transport._buffer)
transport._fatal_error.assert_called_with(
err,
'Fatal write error on socket transport')

@mock.patch('asyncio.selector_events.logger')
def test_write_exception(self, m_log):
Expand Down