From 273ca3de7744cccfd4ffc36bc8ac4b66a1485940 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 13 Jul 2025 16:39:50 +0100 Subject: [PATCH] Re-entrancy guard for sym/fp change timers. (Potentially KICAD-XJN.) --- eeschema/sch_base_frame.cpp | 13 ++++++++++++- eeschema/sch_base_frame.h | 1 + include/pcb_base_frame.h | 11 ++++++----- pcbnew/pcb_base_frame.cpp | 21 ++++++++++++++++++--- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 5f131263dd..a4c67a27f9 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -100,7 +100,8 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindo EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, aSize, aStyle, aFrameName, schIUScale ), m_base_frame_defaults( nullptr, "base_Frame_defaults" ), - m_selectionFilterPanel( nullptr ) + m_selectionFilterPanel( nullptr ), + m_inSymChangeTimerEvent( false ) { if( ( aStyle & wxFRAME_NO_TASKBAR ) == 0 ) createCanvas(); @@ -765,6 +766,12 @@ void SCH_BASE_FRAME::OnSymChangeDebounceTimer( wxTimerEvent& aEvent ) return; } + if( m_inSymChangeTimerEvent ) + { + wxLogTrace( "KICAD_LIB_WATCH", "Restarting debounce timer" ); + m_watcherDebounceTimer.StartOnce( 3000 ); + } + wxLogTrace( "KICAD_LIB_WATCH", "OnSymChangeDebounceTimer" ); // Disable logging to avoid spurious messages and check if the file has changed @@ -777,6 +784,8 @@ void SCH_BASE_FRAME::OnSymChangeDebounceTimer( wxTimerEvent& aEvent ) m_watcherLastModified = lastModified; + m_inSymChangeTimerEvent = true; + if( !GetScreen()->IsContentModified() || IsOK( this, _( "The library containing the current symbol has changed.\n" "Do you want to reload the library?" ) ) ) @@ -786,6 +795,8 @@ void SCH_BASE_FRAME::OnSymChangeDebounceTimer( wxTimerEvent& aEvent ) Kiway().ExpressMail( FRAME_SCH_VIEWER, MAIL_REFRESH_SYMBOL, libName ); Kiway().ExpressMail( FRAME_SCH_SYMBOL_EDITOR, MAIL_REFRESH_SYMBOL, libName ); } + + m_inSymChangeTimerEvent = false; } diff --git a/eeschema/sch_base_frame.h b/eeschema/sch_base_frame.h index 8c876b5c90..8c4790e030 100644 --- a/eeschema/sch_base_frame.h +++ b/eeschema/sch_base_frame.h @@ -308,6 +308,7 @@ private: wxFileName m_watcherFileName; wxDateTime m_watcherLastModified; wxTimer m_watcherDebounceTimer; + bool m_inSymChangeTimerEvent; std::unique_ptr m_spaceMouse; }; diff --git a/include/pcb_base_frame.h b/include/pcb_base_frame.h index 9740e3eeff..a3fb4ce6fd 100644 --- a/include/pcb_base_frame.h +++ b/include/pcb_base_frame.h @@ -435,12 +435,13 @@ protected: PCB_ORIGIN_TRANSFORMS m_originTransforms; private: - std::unique_ptr m_spaceMouse; + std::unique_ptr m_spaceMouse; - std::unique_ptr m_watcher; - wxFileName m_watcherFileName; - wxDateTime m_watcherLastModified; - wxTimer m_watcherDebounceTimer; + std::unique_ptr m_watcher; + wxFileName m_watcherFileName; + wxDateTime m_watcherLastModified; + wxTimer m_watcherDebounceTimer; + bool m_inFpChangeTimerEvent; std::vector m_boardChangeListeners; }; diff --git a/pcbnew/pcb_base_frame.cpp b/pcbnew/pcb_base_frame.cpp index d9eb7ebf02..5d2f45bac4 100644 --- a/pcbnew/pcb_base_frame.cpp +++ b/pcbnew/pcb_base_frame.cpp @@ -81,7 +81,8 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName, pcbIUScale ), m_pcb( nullptr ), - m_originTransforms( *this ) + m_originTransforms( *this ), + m_inFpChangeTimerEvent( false ) { m_watcherDebounceTimer.Bind( wxEVT_TIMER, &PCB_BASE_FRAME::OnFpChangeDebounceTimer, this ); } @@ -1182,6 +1183,18 @@ void PCB_BASE_FRAME::OnFPChange( wxFileSystemWatcherEvent& aEvent ) void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent ) { + if( aEvent.GetId() != m_watcherDebounceTimer.GetId() ) + { + aEvent.Skip(); + return; + } + + if( m_inFpChangeTimerEvent ) + { + wxLogTrace( "KICAD_LIB_WATCH", "Restarting debounce timer" ); + m_watcherDebounceTimer.StartOnce( 3000 ); + } + wxLogTrace( "KICAD_LIB_WATCH", "OnFpChangeDebounceTimer" ); // Disable logging to avoid spurious messages and check if the file has changed @@ -1204,6 +1217,8 @@ void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent ) if( !fp || !tbl ) return; + m_inFpChangeTimerEvent = true; + if( !GetScreen()->IsContentModified() || IsOK( this, _( "The library containing the current footprint has changed.\n" "Do you want to reload the footprint?" ) ) ) @@ -1220,9 +1235,7 @@ void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent ) std::vector selectedItems; for( const EDA_ITEM* item : GetCurrentSelection() ) - { selectedItems.emplace_back( item->m_Uuid ); - } m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); @@ -1250,4 +1263,6 @@ void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent ) DisplayError( this, ioe.What() ); } } + + m_inFpChangeTimerEvent = false; }