diff --git a/mercurial/worker.py b/mercurial/worker.py
index 4c57ce494a4e7ddd561a637abee09b2a9e680eb2_bWVyY3VyaWFsL3dvcmtlci5weQ==..5207225239557efd1d7d0bb5d5093763dca5191b_bWVyY3VyaWFsL3dvcmtlci5weQ== 100644
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -79,25 +79,6 @@
     def __init__(self, wrapped):
         self._wrapped = wrapped
 
-    # Do NOT implement readinto() by making it delegate to
-    # _wrapped.readinto(), since that is unbuffered. The unpickler is fine
-    # with just read() and readline(), so we don't need to implement it.
-
-    if (3, 8, 0) <= sys.version_info[:3] < (3, 8, 2):
-
-        # This is required for python 3.8, prior to 3.8.2.  See issue6444.
-        def readinto(self, b):
-            pos = 0
-            size = len(b)
-
-            while pos < size:
-                ret = self._wrapped.readinto(b[pos:])
-                if not ret:
-                    break
-                pos += ret
-
-            return pos
-
     def readline(self):
         return self._wrapped.readline()
 
@@ -101,10 +82,5 @@
     def readline(self):
         return self._wrapped.readline()
 
-    # issue multiple reads until size is fulfilled (or EOF is encountered)
-    def read(self, size=-1):
-        if size < 0:
-            return self._wrapped.readall()
-
-        buf = bytearray(size)
+    def readinto(self, buf):
         pos = 0
@@ -110,4 +86,5 @@
         pos = 0
+        size = len(buf)
 
         with memoryview(buf) as view:
             while pos < size:
@@ -117,7 +94,16 @@
                     break
                 pos += ret
 
-        del buf[pos:]
+        return pos
+
+    # issue multiple reads until size is fulfilled (or EOF is encountered)
+    def read(self, size=-1):
+        if size < 0:
+            return self._wrapped.readall()
+
+        buf = bytearray(size)
+        n_read = self.readinto(buf)
+        del buf[n_read:]
         return bytes(buf)