diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index 9edcd415..9452e957 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -148,10 +148,10 @@ bool Profiler::ShouldExit() return s_instance->m_shutdown.load( std::memory_order_relaxed ); } +enum { BulkSize = TargetFrameSize / QueueItemSize }; + void Profiler::Worker() { - enum { BulkSize = TargetFrameSize / QueueItemSize }; - const auto procname = GetProcessName(); const auto pnsz = std::min( strlen( procname ), WelcomeMessageProgramNameSize - 1 ); @@ -192,25 +192,14 @@ void Profiler::Worker() for(;;) { - QueueItem item[BulkSize]; - const auto sz = s_queue.try_dequeue_bulk( token, item, BulkSize ); - if( sz > 0 ) + const auto status = Dequeue( token ); + if( status == ConnectionLost ) { - auto buf = m_buffer + m_bufferOffset; - auto ptr = buf; - for( size_t i=0; i TargetFrameSize * 2 ) m_bufferOffset = 0; + break; } - else + else if( status == QueueEmpty ) { - if( ShouldExit() ) return; + if( ShouldExit() ) break; std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); } @@ -219,7 +208,49 @@ void Profiler::Worker() if( !HandleServerQuery() ) break; } } + if( ShouldExit() ) break; } + + QueueItem terminate; + terminate.hdr.type = QueueType::Terminate; + if( !SendData( (const char*)&terminate, 1 ) ) return; + for(;;) + { + if( m_sock->HasData() ) + { + while( m_sock->HasData() ) if( !HandleServerQuery() ) return; + while( Dequeue( token ) == Success ) {} + } + else + { + std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); + } + } +} + +Profiler::DequeueStatus Profiler::Dequeue( moodycamel::ConsumerToken& token ) +{ + QueueItem item[BulkSize]; + const auto sz = s_queue.try_dequeue_bulk( token, item, BulkSize ); + if( sz > 0 ) + { + auto buf = m_buffer + m_bufferOffset; + auto ptr = buf; + for( size_t i=0; i TargetFrameSize * 2 ) m_bufferOffset = 0; + } + else + { + return QueueEmpty; + } + return Success; } bool Profiler::SendData( const char* data, size_t len ) @@ -322,6 +353,8 @@ bool Profiler::HandleServerQuery() case ServerQueryMessageLiteral: SendString( ptr, (const char*)ptr, QueueType::MessageData ); break; + case ServerQueryTerminate: + return false; default: assert( false ); break; diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index ae8790af..aa2e8bc8 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -162,9 +162,13 @@ public: static bool ShouldExit(); private: + enum DequeueStatus { Success, ConnectionLost, QueueEmpty }; + static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); } void Worker(); + DequeueStatus Dequeue( moodycamel::ConsumerToken& token ); + bool SendData( const char* data, size_t len ); bool SendString( uint64_t ptr, const char* str, QueueType type ); void SendSourceLocation( uint64_t ptr ); diff --git a/common/TracyProtocol.hpp b/common/TracyProtocol.hpp index 36999a62..439057e2 100644 --- a/common/TracyProtocol.hpp +++ b/common/TracyProtocol.hpp @@ -18,6 +18,7 @@ static_assert( TargetFrameSize * 2 >= 64 * 1024, "Not enough space for LZ4 strea enum ServerQuery : uint8_t { + ServerQueryTerminate, ServerQueryString, ServerQueryThreadString, ServerQueryCustomString, diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 5c148d6b..d2814e99 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -8,6 +8,7 @@ namespace tracy enum class QueueType : uint8_t { + Terminate, ZoneBegin, ZoneEnd, StringData, @@ -170,6 +171,7 @@ struct QueueItem enum { QueueItemSize = sizeof( QueueItem ) }; static const size_t QueueDataSize[] = { + sizeof( QueueHeader ), // terminate sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), sizeof( QueueHeader ) + sizeof( QueueZoneEnd ), sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data diff --git a/server/TracyView.cpp b/server/TracyView.cpp index ce729745..d28d503c 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -76,6 +76,7 @@ View::View( const char* addr ) , m_drawZones( true ) , m_drawLocks( true ) , m_drawPlots( true ) + , m_terminate( false ) { assert( s_instance == nullptr ); s_instance = this; @@ -109,6 +110,7 @@ View::View( FileRead& f ) , m_drawZones( true ) , m_drawLocks( true ) , m_drawPlots( true ) + , m_terminate( false ) { assert( s_instance == nullptr ); s_instance = this; @@ -384,6 +386,27 @@ void View::Worker() t0 = t1; bytes = 0; } + + if( m_terminate ) + { + if( !m_pendingStrings.empty() || !m_pendingThreads.empty() || !m_pendingSourceLocation.empty() || + !m_pendingCustomStrings.empty() || !m_pendingPlots.empty() || !m_pendingMessages.empty() ) + { + continue; + } + bool done = true; + for( auto& v : m_zoneStack ) + { + if( !v.second.empty() ) + { + done = false; + break; + } + } + if( !done ) continue; + ServerQuery( ServerQueryTerminate, 0 ); + break; + } } close: @@ -519,6 +542,9 @@ void View::Process( const QueueItem& ev ) case QueueType::MessageLiteral: ProcessMessage( ev.message, true ); break; + case QueueType::Terminate: + m_terminate = true; + break; default: assert( false ); break; diff --git a/server/TracyView.hpp b/server/TracyView.hpp index bff22ec8..5c5e9623 100644 --- a/server/TracyView.hpp +++ b/server/TracyView.hpp @@ -247,6 +247,8 @@ private: bool m_drawZones; bool m_drawLocks; bool m_drawPlots; + + bool m_terminate; }; }