MCPcopy Index your code
hub / github.com/python/cpython / _sendfile_zerocopy

Method _sendfile_zerocopy

Lib/socket.py:352–420  ·  view source on GitHub ↗

Send a file using a zero-copy function.

(self, zerocopy_func, giveup_exc_type, file,
                           offset=0, count=None)

Source from the content-addressed store, hash-verified

350 return text
351
352 def _sendfile_zerocopy(self, zerocopy_func, giveup_exc_type, file,
353 offset=0, count=None):
354 """
355 Send a file using a zero-copy function.
356 """
357 import selectors
358
359 self._check_sendfile_params(file, offset, count)
360 sockno = self.fileno()
361 try:
362 fileno = file.fileno()
363 except (AttributeError, io.UnsupportedOperation) as err:
364 raise giveup_exc_type(err) # not a regular file
365 try:
366 fsize = os.fstat(fileno).st_size
367 except OSError as err:
368 raise giveup_exc_type(err) # not a regular file
369 if not fsize:
370 return 0 # empty file
371 # Truncate to 1GiB to avoid OverflowError, see bpo-38319.
372 blocksize = min(count or fsize, 2 ** 30)
373 timeout = self.gettimeout()
374 if timeout == 0:
375 raise ValueError("non-blocking sockets are not supported")
376 # poll/select have the advantage of not requiring any
377 # extra file descriptor, contrarily to epoll/kqueue
378 # (also, they require a single syscall).
379 if hasattr(selectors, 'PollSelector'):
380 selector = selectors.PollSelector()
381 else:
382 selector = selectors.SelectSelector()
383 selector.register(sockno, selectors.EVENT_WRITE)
384
385 total_sent = 0
386 # localize variable access to minimize overhead
387 selector_select = selector.select
388 try:
389 while True:
390 if timeout and not selector_select(timeout):
391 raise TimeoutError('timed out')
392 if count:
393 blocksize = min(count - total_sent, blocksize)
394 if blocksize <= 0:
395 break
396 try:
397 sent = zerocopy_func(fileno, offset, blocksize)
398 except BlockingIOError:
399 if not timeout:
400 # Block until the socket is ready to send some
401 # data; avoids hogging CPU resources.
402 selector_select()
403 continue
404 except OSError as err:
405 if total_sent == 0:
406 # We can get here for different reasons, the main
407 # one being 'file' is not a regular mmap(2)-like
408 # file, in which case we'll fall back on using
409 # plain send().

Callers 2

sendfileMethod · 0.80

Calls 6

registerMethod · 0.95
TimeoutErrorClass · 0.85
filenoMethod · 0.45
gettimeoutMethod · 0.45
seekMethod · 0.45

Tested by

no test coverage detected