mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
bpo-32410: Avoid blocking on file IO in sendfile fallback code (GH-7172) (#7182)
(cherry picked from commit 7165754b6b
)
Co-authored-by: Yury Selivanov <yury@magic.io>
This commit is contained in:
parent
a379dea11e
commit
420092e255
5 changed files with 24 additions and 2 deletions
|
@ -800,7 +800,10 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
async def _sock_sendfile_fallback(self, sock, file, offset, count):
|
async def _sock_sendfile_fallback(self, sock, file, offset, count):
|
||||||
if offset:
|
if offset:
|
||||||
file.seek(offset)
|
file.seek(offset)
|
||||||
blocksize = min(count, 16384) if count else 16384
|
blocksize = (
|
||||||
|
min(count, constants.SENDFILE_FALLBACK_READBUFFER_SIZE)
|
||||||
|
if count else constants.SENDFILE_FALLBACK_READBUFFER_SIZE
|
||||||
|
)
|
||||||
buf = bytearray(blocksize)
|
buf = bytearray(blocksize)
|
||||||
total_sent = 0
|
total_sent = 0
|
||||||
try:
|
try:
|
||||||
|
@ -810,7 +813,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
if blocksize <= 0:
|
if blocksize <= 0:
|
||||||
break
|
break
|
||||||
view = memoryview(buf)[:blocksize]
|
view = memoryview(buf)[:blocksize]
|
||||||
read = file.readinto(view)
|
read = await self.run_in_executor(None, file.readinto, view)
|
||||||
if not read:
|
if not read:
|
||||||
break # EOF
|
break # EOF
|
||||||
await self.sock_sendall(sock, view)
|
await self.sock_sendall(sock, view)
|
||||||
|
|
|
@ -14,6 +14,10 @@ DEBUG_STACK_DEPTH = 10
|
||||||
# Number of seconds to wait for SSL handshake to complete
|
# Number of seconds to wait for SSL handshake to complete
|
||||||
SSL_HANDSHAKE_TIMEOUT = 10.0
|
SSL_HANDSHAKE_TIMEOUT = 10.0
|
||||||
|
|
||||||
|
# Used in sendfile fallback code. We use fallback for platforms
|
||||||
|
# that don't support sendfile, or for TLS connections.
|
||||||
|
SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 256
|
||||||
|
|
||||||
# The enum should be here to break circular dependencies between
|
# The enum should be here to break circular dependencies between
|
||||||
# base_events and sslproto
|
# base_events and sslproto
|
||||||
class _SendfileMode(enum.Enum):
|
class _SendfileMode(enum.Enum):
|
||||||
|
|
|
@ -1818,12 +1818,15 @@ class BaseLoopSockSendfileTests(test_utils.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
cls.__old_bufsize = constants.SENDFILE_FALLBACK_READBUFFER_SIZE
|
||||||
|
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 16
|
||||||
with open(support.TESTFN, 'wb') as fp:
|
with open(support.TESTFN, 'wb') as fp:
|
||||||
fp.write(cls.DATA)
|
fp.write(cls.DATA)
|
||||||
super().setUpClass()
|
super().setUpClass()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
|
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = cls.__old_bufsize
|
||||||
support.unlink(support.TESTFN)
|
support.unlink(support.TESTFN)
|
||||||
super().tearDownClass()
|
super().tearDownClass()
|
||||||
|
|
||||||
|
|
|
@ -2160,6 +2160,17 @@ class SockSendfileMixin(SendfileBase):
|
||||||
async def wait_closed(self):
|
async def wait_closed(self):
|
||||||
await self.fut
|
await self.fut
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.__old_bufsize = constants.SENDFILE_FALLBACK_READBUFFER_SIZE
|
||||||
|
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 16
|
||||||
|
super().setUpClass()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
constants.SENDFILE_FALLBACK_READBUFFER_SIZE = cls.__old_bufsize
|
||||||
|
super().tearDownClass()
|
||||||
|
|
||||||
def set_socket_opts(self, sock):
|
def set_socket_opts(self, sock):
|
||||||
# On macOS, SO_SNDBUF is reset by connect(). So this method
|
# On macOS, SO_SNDBUF is reset by connect(). So this method
|
||||||
# should be called after the socket is connected.
|
# should be called after the socket is connected.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Avoid blocking on file IO in sendfile fallback code
|
Loading…
Add table
Add a link
Reference in a new issue