From 7dc7ece2bda3f27485eae5a61a8757b7b30741a2 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Thu, 27 Jun 2019 13:04:27 +0200 Subject: [PATCH] Add staging area for frame images. Compressing frame images on a separate thread may cause frame image arrival before frames are sent. Fix this issue by creating a staging area in which frame images will wait for frames to arrive. This probably breaks playback functionality, as non-existent frames may be queried, but this problem seems to be very hard to find, so let's ignore it for now. --- server/TracyWorker.cpp | 36 +++++++++++++++++++++++++++--------- server/TracyWorker.hpp | 1 + 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 56ed92c9..259cb4ce 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -2951,10 +2951,18 @@ void Worker::ProcessFrameMark( const QueueFrameMark& ev ) Query( ServerQueryFrameName, name ); } ); + int32_t frameImage = -1; + auto fis = m_frameImageStaging.find( fd->frames.size() ); + if( fis != m_frameImageStaging.end() ) + { + frameImage = fis->second; + m_frameImageStaging.erase( fis ); + } + assert( fd->continuous == 1 ); const auto time = TscTime( ev.time ); assert( fd->frames.empty() || fd->frames.back().start <= time ); - fd->frames.push_back( FrameEvent{ time, -1, -1 } ); + fd->frames.push_back( FrameEvent{ time, -1, frameImage } ); m_data.lastTime = std::max( m_data.lastTime, time ); } @@ -3006,7 +3014,6 @@ void Worker::ProcessFrameImage( const QueueFrameImage& ev ) auto& frames = m_data.framesBase->frames; const auto fidx = ev.frame - m_data.frameOffset + 1; - assert( fidx < frames.size() ); if( m_onDemand && fidx <= 1 ) { m_pendingFrameImageData.erase( it ); @@ -3017,11 +3024,6 @@ void Worker::ProcessFrameImage( const QueueFrameImage& ev ) FrameImageIndexFailure(); return; } - if( frames[fidx].frameImage >= 0 ) - { - FrameImageTwiceFailure(); - return; - } auto fi = m_slab.Alloc(); fi->ptr = PackFrameImage( (const char*)it->second, ev.w, ev.h, fi->csz ); @@ -3032,9 +3034,25 @@ void Worker::ProcessFrameImage( const QueueFrameImage& ev ) const auto idx = m_data.frameImage.size(); m_data.frameImage.push_back( fi ); - frames[fidx].frameImage = idx; - m_pendingFrameImageData.erase( it ); + + if( fidx >= frames.size() ) + { + if( m_frameImageStaging.find( fidx ) != m_frameImageStaging.end() ) + { + FrameImageTwiceFailure(); + return; + } + m_frameImageStaging.emplace( fidx, idx ); + } + else if( frames[fidx].frameImage >= 0 ) + { + FrameImageTwiceFailure(); + } + else + { + frames[fidx].frameImage = idx; + } } void Worker::ProcessZoneText( const QueueZoneText& ev ) diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index ce8add04..ea5894ee 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -543,6 +543,7 @@ private: Vector m_serverQueryQueue; size_t m_serverQuerySpaceLeft; + flat_hash_map m_frameImageStaging; char* m_frameImageBuffer = nullptr; size_t m_frameImageBufferSize = 0; };