From 08cd46cd4c5b3b946532fb5ff7ffc5ca0aaf61a2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 12 Apr 2019 18:49:03 +0400 Subject: [PATCH] Fix crash in streaming caching. --- .../streaming/media_streaming_reader.cpp | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp index 640c35bfa..e6c7426ad 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_reader.cpp @@ -550,17 +550,35 @@ int Reader::Slices::maxSliceSize(int sliceNumber) const { } Reader::SerializedSlice Reader::Slices::serializeAndUnloadUnused() { + using Flag = Slice::Flag; + if (_headerMode == HeaderMode::Unknown || _usedSlices.size() <= kSlicesInMemory) { return {}; } const auto purgeSlice = _usedSlices.front(); _usedSlices.pop_front(); - if (!(_data[purgeSlice].flags & Slice::Flag::LoadedFromCache)) { + if (!(_data[purgeSlice].flags & Flag::LoadedFromCache)) { // If the only data in this slice was from _header, just leave it. return {}; - } else if (_headerMode == HeaderMode::NoCache - || !(_data[purgeSlice].flags & Slice::Flag::ChangedSinceCache)) { + } + const auto noNeedToSaveToCache = [&] { + if (_headerMode == HeaderMode::NoCache) { + // Cache is not used. + return true; + } else if (!(_data[purgeSlice].flags & Flag::ChangedSinceCache)) { + // If no data was changed we should still save first slice, + // if header data was changed since loading from cache. + // Otherwise in destructor we won't be able to unload header. + if (!isGoodHeader() + || (purgeSlice > 0) + || (!(_header.flags & Flag::ChangedSinceCache))) { + return true; + } + } + return false; + }(); + if (noNeedToSaveToCache) { _data[purgeSlice] = Slice(); return {}; }