Skip to content

Commit

Permalink
Write data into socket with payload zero-copy
Browse files Browse the repository at this point in the history
PR #134
Fixes #133
  • Loading branch information
webknjaz committed Oct 23, 2018
1 parent dcfbc4c commit bbc8d95
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
11 changes: 11 additions & 0 deletions cheroot/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,14 @@ def assert_native(n):
"""
if not isinstance(n, str):
raise TypeError('n must be a native str (got %s)' % type(n).__name__)


if six.PY3:
"""Python 3 has memoryview builtin."""
# Python 2.7 has it backported, but socket.write() does
# str(memoryview(b'0' * 100)) -> <memory at 0x7fb6913a5588>
# instead of accessing it correctly.
memoryview = memoryview
else:
"""Link memoryview to buffer under Python 2."""
memoryview = buffer # noqa: F821
9 changes: 6 additions & 3 deletions cheroot/makefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import six

from . import errors
from ._compat import memoryview


class BufferedWriter(io.BufferedWriter):
Expand Down Expand Up @@ -64,10 +65,12 @@ def _drop(self):

def write(self, data):
"""Sendall for non-blocking sockets."""
while data:
bytes_sent = 0
data_mv = memoryview(data)
payload_size = len(data_mv)
while bytes_sent < payload_size:
try:
bytes_sent = self.send(data)
data = data[bytes_sent:]
bytes_sent += self.send(data_mv[bytes_sent:])
except socket.error as e:
if e.args[0] not in errors.socket_errors_nonblocking:
raise
Expand Down

0 comments on commit bbc8d95

Please sign in to comment.