8000 bpo-32410: Avoid blocking on file IO in sendfile fallback code (GH-71… · python/cpython@420092e · GitHub
[go: up one dir, main page]

Skip to content

Commit 420092e

Browse files
miss-islington1st1
authored andcommitted
bpo-32410: Avoid blocking on file IO in sendfile fallback code (GH-7172) (#7182)
(cherry picked from commit 7165754) Co-authored-by: Yury Selivanov <yury@magic.io>
1 parent a379dea commit 420092e

File tree

5 files changed

+24
-2
lines changed

5 files changed

+24
-2
lines changed

Lib/asyncio/base_events.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,10 @@ async def _sock_sendfile_native(self, sock, file, offset, count):
800800
async def _sock_sendfile_fallback(self, sock, file, offset, count):
801801
if offset:
802802
file.seek(offset)
803-
blocksize = min(count, 16384) if count else 16384
803+
blocksize = (
804+
min(count, constants.SENDFILE_FALLBACK_READBUFFER_SIZE)
805+
if count else constants.SENDFILE_FALLBACK_READBUFFER_SIZE
806+
)
804807
buf = bytearray(blocksize)
805808
total_sent = 0
806809
try:
@@ -810,7 +813,7 @@ async def _sock_sendfile_fallback(self, sock, file, offset, count):
810813
if blocksize <= 0:
811814
break
812815
view = memoryview(buf)[:blocksize]
813-
read = file.readinto(view)
816+
read = await self.run_in_executor(None, file.readinto, view)
814817
if not read:
815818
break # EOF
816819
await self.sock_sendall(sock, view)

Lib/asyncio/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
# Number of seconds to wait for SSL handshake to complete
1515
SSL_HANDSHAKE_TIMEOUT = 10.0
1616

17+
# Used in sendfile fallback code. We use fallback for platforms
18+
# that don't support sendfile, or for TLS connections.
19+
SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 256
20+
1721
# The enum should be here to break circular dependencies between
1822
# base_events and sslproto
1923
class _SendfileMode(enum.Enum):

Lib/test/test_asyncio/test_base_events.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,12 +1818,15 @@ async def wait_closed(self):
18181818

18191819
@classmethod
18201820
def setUpClass(cls):
1821+
cls.__old_bufsize = constants.SENDFILE_FALLBACK_READBUFFER_SIZE
1822+
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 16
18211823
with open(support.TESTFN, 'wb') as fp:
18221824
fp.write(cls.DATA)
18231825
super().setUpClass()
18241826

18251827
@classmethod
18261828
def tearDownClass(cls):
1829+
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = cls.__old_bufsize
18271830
support.unlink(support.TESTFN)
18281831
super().tearDownClass()
18291832

Lib/test/test_asyncio/test_events.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,6 +2160,17 @@ def connection_lost(self, exc):
21602160
async def wait_closed(self):
21612161
await self.fut
21622162

2163+
@classmethod
2164+
def setUpClass(cls):
2165+
cls.__old_bufsize = constants.SENDFILE_FALLBACK_READBUFFER_SIZE
2166+
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 16
2167+
super().setUpClass()
2168+
2169+
@classmethod
2170+
def tearDownClass(cls):
2171+
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = cls.__old_bufsize
2172+
super().tearDownClass()
2173+
21632174
def set_socket_opts(self, sock):
21642175
# On macOS, SO_SNDBUF is reset by connect(). So this method
21652176
# should be called after the socket is connected.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Avoid blocking on file IO in sendfile fallback code

0 commit comments

Comments
 (0)
0