Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
add socket._sendfile_use_transmitfile
  • Loading branch information
aisk committed Nov 23, 2023
commit 490df91637b86087b6017d8d104f3f10791cc429
23 changes: 23 additions & 0 deletions Lib/socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
import os, sys, io, selectors
from enum import IntEnum, IntFlag

try:
import _overlapped
import msvcrt
except ImportError:
_overlapped = None
msvcrt = None

try:
import errno
except ImportError:
Expand Down Expand Up @@ -451,6 +458,22 @@ def _sendfile_use_send(self, file, offset=0, count=None):
if total_sent > 0 and hasattr(file, 'seek'):
file.seek(offset + total_sent)

if _overlapped:
Comment thread
aisk marked this conversation as resolved.
Outdated
def _sendfile_use_transmitfile(self, file, offset=0, count=None):
self._check_sendfile_params(file, offset, count)
if self.gettimeout() == 0:
raise ValueError("non-blocking sockets are not supported")
ov = _overlapped.Overlapped()
offset_low = offset & 0xffff_ffff
offset_high = (offset >> 32) & 0xffff_ffff
count = count or 0
ov.TransmitFile(self.fileno(), msvcrt.get_osfhandle(file.fileno()),
offset_low, offset_high, count, 0, 0)
sent = ov.getresult(True)
if sent > 0 and hasattr(file, 'seek'):
file.seek(offset + sent)
return sent

def _check_sendfile_params(self, file, offset, count):
if 'b' not in getattr(file, 'mode', 'b'):
raise ValueError("file should be opened in binary mode")
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -6421,6 +6421,14 @@ def meth_from_sock(self, sock):
return getattr(sock, "_sendfile_use_sendfile")


class SendfileUsingTransmitfileTest(SendfileUsingSendTest):
"""
Test the TransmitFile() implementation of socket.sendfile().
"""
def meth_from_sock(self, sock):
return getattr(sock, "_sendfile_use_transmitfile")


@unittest.skipUnless(HAVE_SOCKET_ALG, 'AF_ALG required')
class LinuxKernelCryptoAPI(unittest.TestCase):
# tests for AF_ALG
Expand Down