diff --git a/src/FlexRayAnalyzer.cpp b/src/FlexRayAnalyzer.cpp index 35abe04..bbf589f 100644 --- a/src/FlexRayAnalyzer.cpp +++ b/src/FlexRayAnalyzer.cpp @@ -196,6 +196,16 @@ void FlexRayAnalyzer::WorkerThread() mResults->AddFrameV2( frame_v2, frame_v2_type, start_sample, std::max( start_sample, end_sample ) ); }; + U64 reported_progress_sample = 0; + + auto report_progress = [&]( U64 sample_number ) { + if( sample_number > reported_progress_sample ) + { + reported_progress_sample = sample_number; + ReportProgress( reported_progress_sample ); + } + }; + auto commit_record = [&]( U64 start_sample, U64 end_sample, U8 frame_flags, FlexRayFrameRecord record ) { record.mStartSample = start_sample; record.mEndSample = end_sample; @@ -204,7 +214,7 @@ void FlexRayAnalyzer::WorkerThread() mSettings.mInputChannel ); mResults->CommitFlexRayPacket( std::move( record ) ); mResults->CommitResults(); - ReportProgress( end_sample ); + report_progress( end_sample ); CheckIfThreadShouldExit(); }; @@ -234,6 +244,12 @@ void FlexRayAnalyzer::WorkerThread() for( ;; ) { + // Report progress and honor cancellation even when no packets are being + // committed (idle line, noise, wrong settings), so the analyzer never + // appears stuck and can always be removed or re-run promptly. + report_progress( mInput->GetSampleNumber() ); + CheckIfThreadShouldExit(); + U64 preceding_high_start_sample = 0; U64 tss_start_sample = 0; bool bypass_idle_check = false; diff --git a/src/FlexRayAnalyzerResults.cpp b/src/FlexRayAnalyzerResults.cpp index b300272..e3847fb 100644 --- a/src/FlexRayAnalyzerResults.cpp +++ b/src/FlexRayAnalyzerResults.cpp @@ -64,33 +64,47 @@ FlexRayAnalyzerResults::FlexRayAnalyzerResults( FlexRayAnalyzer* analyzer, FlexR void FlexRayAnalyzerResults::AddFlexRaySegment( const Frame& frame, FlexRaySegmentRecord record ) { - mSegmentRecords.push_back( std::move( record ) ); + { + std::lock_guard lock( mRecordsMutex ); + mSegmentRecords.push_back( std::move( record ) ); + } AddFrame( frame ); } U64 FlexRayAnalyzerResults::CommitFlexRayPacket( FlexRayFrameRecord record ) { - mPacketRecords.push_back( std::move( record ) ); + { + std::lock_guard lock( mRecordsMutex ); + mPacketRecords.push_back( std::move( record ) ); + } return CommitPacketAndStartNewPacket(); } -const FlexRaySegmentRecord& FlexRayAnalyzerResults::GetSegmentRecord( U64 frame_index ) const +FlexRaySegmentRecord FlexRayAnalyzerResults::GetSegmentRecord( U64 frame_index ) const { + std::lock_guard lock( mRecordsMutex ); return mSegmentRecords.at( static_cast( frame_index ) ); } -const FlexRayFrameRecord& FlexRayAnalyzerResults::GetPacketRecord( U64 packet_index ) const +FlexRayFrameRecord FlexRayAnalyzerResults::GetPacketRecord( U64 packet_index ) const { + std::lock_guard lock( mRecordsMutex ); return mPacketRecords.at( static_cast( packet_index ) ); } +U64 FlexRayAnalyzerResults::GetPacketRecordCount() const +{ + std::lock_guard lock( mRecordsMutex ); + return static_cast( mPacketRecords.size() ); +} + void FlexRayAnalyzerResults::GenerateBubbleText( U64 frame_index, Channel& channel, DisplayBase display_base ) { (void)channel; (void)display_base; ClearResultStrings(); - const FlexRaySegmentRecord& record = GetSegmentRecord( frame_index ); + const FlexRaySegmentRecord record = GetSegmentRecord( frame_index ); AddResultString( record.mShortText.c_str() ); if( !record.mLongText.empty() && record.mLongText != record.mShortText ) @@ -108,10 +122,10 @@ void FlexRayAnalyzerResults::GenerateExportFile( const char* file, DisplayBase d file_stream << "Time [s],Type,Segment,Frame ID,Cycle,TSS Bits,TSS TX Spec OK,Payload Bytes,PPI,NF,Sync,Startup,Header CRC,Header CRC OK,Frame CRC,Frame CRC OK,Payload,Info" << std::endl; - U64 num_packets = static_cast( mPacketRecords.size() ); + U64 num_packets = GetPacketRecordCount(); for( U64 i = 0; i < num_packets; ++i ) { - const FlexRayFrameRecord& record = GetPacketRecord( i ); + const FlexRayFrameRecord record = GetPacketRecord( i ); char time_str[128]; AnalyzerHelpers::GetTimeString( record.mStartSample, trigger_sample, sample_rate, time_str, 128 ); @@ -163,7 +177,7 @@ void FlexRayAnalyzerResults::GenerateFrameTabularText( U64 frame_index, DisplayB #ifdef SUPPORTS_PROTOCOL_SEARCH (void)display_base; ClearTabularText(); - const FlexRaySegmentRecord& record = GetSegmentRecord( frame_index ); + const FlexRaySegmentRecord record = GetSegmentRecord( frame_index ); AddTabularText( record.mLongText.empty() ? record.mShortText.c_str() : record.mLongText.c_str() ); #endif } diff --git a/src/FlexRayAnalyzerResults.h b/src/FlexRayAnalyzerResults.h index 8043006..3809ce8 100644 --- a/src/FlexRayAnalyzerResults.h +++ b/src/FlexRayAnalyzerResults.h @@ -2,6 +2,7 @@ #define FLEXRAY_ANALYZER_RESULTS #include +#include #include #include @@ -77,12 +78,17 @@ class FlexRayAnalyzerResults : public AnalyzerResults U64 CommitFlexRayPacket( FlexRayFrameRecord record ); protected: - const FlexRaySegmentRecord& GetSegmentRecord( U64 frame_index ) const; - const FlexRayFrameRecord& GetPacketRecord( U64 packet_index ) const; + // The worker thread appends records while the application reads them from other + // threads (bubble text, tabular text, export), so every access must hold the lock. + // The getters therefore return copies instead of references into the vectors. + FlexRaySegmentRecord GetSegmentRecord( U64 frame_index ) const; + FlexRayFrameRecord GetPacketRecord( U64 packet_index ) const; + U64 GetPacketRecordCount() const; protected: FlexRayAnalyzerSettings* mSettings; FlexRayAnalyzer* mAnalyzer; + mutable std::mutex mRecordsMutex; std::vector mSegmentRecords; std::vector mPacketRecords; };