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
Hash data against stored hasher safely
        :param Descriptor self: this