docs: def perform_chunked_integrity_check(self):
          # type: (Descriptor) -> None
          """Hash data against stored hasher safely
          :param Descriptor self: this
          """
          hasher = self.hmac or self.md5
          # iterate from next chunk to be checked
          while True:
              ucc = None
              with self._meta_lock:
                  chunk_num = self._next_integrity_chunk
                  # check if the next chunk is ready
                  if (chunk_num in self._unchecked_chunks and
                          self._unchecked_chunks[chunk_num]['decrypted']):
                      ucc = self._unchecked_chunks.pop(chunk_num)['ucc']
                  else:
                      break
              # hash data and set next integrity chunk
              md5hexdigest = None
              if hasher is not None:
                  with ucc.file_path.open('rb') as fd:
                      if not ucc.temp:
                          fd.seek(ucc.fd_start, 0)
                      chunk = fd.read(ucc.data_len)
                  if ucc.temp:
                      ucc.file_path.unlink()
                  with self._hasher_lock:
                      hasher.update(chunk)
                      if hasher == self.md5:
                          md5hexdigest = hasher.hexdigest()
              with self._meta_lock:
                  # update integrity counter and resume db
                  self._next_integrity_chunk += 1
                  if self.is_resumable:
                      self._resume_mgr.add_or_update_record(
                          self.final_path, self._ase, self._chunk_size,
                          self._next_integrity_chunk, False, md5hexdigest,
                      )
                  # decrement outstanding op counter
                  self._outstanding_ops -= 1