Mercurial > hg
changeset 37587:192b7ad06932
keepalive: rewrite readinto() to not use read()
It turns out http.client on Python 3 sometimes uses readinto() in the
implementation of read(). Unfortunately, Python 2 doesn't have a
readinto() in httplib's client, so we have to support both codepaths.
Subclassing is bad, folks.
Differential Revision: https://phab.mercurial-scm.org/D3246
author | Augie Fackler <augie@google.com> |
---|---|
date | Wed, 11 Apr 2018 14:39:49 -0400 |
parents | b94fecf4cd8c |
children | 165a77f7ec13 |
files | mercurial/keepalive.py |
diffstat | 1 files changed, 19 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/keepalive.py Thu Apr 12 17:22:59 2018 +0530 +++ b/mercurial/keepalive.py Wed Apr 11 14:39:49 2018 -0400 @@ -384,6 +384,7 @@ self._connection = None # (same) _raw_read = httplib.HTTPResponse.read + _raw_readinto = getattr(httplib.HTTPResponse, 'readinto', None) def close(self): if self.fp: @@ -523,12 +524,24 @@ return list def readinto(self, dest): - res = self.read(len(dest)) - if not res: - return 0 - - dest[0:len(res)] = res - return len(res) + if self._raw_readinto is None: + res = self.read(len(dest)) + if not res: + return 0 + dest[0:len(res)] = res + return len(res) + total = len(dest) + have = len(self._rbuf) + if have >= total: + dest[0:total] = self._rbuf[:total] + self._rbuf = self._rbuf[total:] + return total + mv = memoryview(dest) + got = self._raw_readinto(mv[have:total]) + dest[0:have] = self._rbuf + got += len(self._rbuf) + self._rbuf = '' + return got def safesend(self, str): """Send `str' to the server.