Re-entrancy guard for sym/fp change timers.

(Potentially KICAD-XJN.)
This commit is contained in:
Jeff Young 2025-07-13 16:39:50 +01:00
parent d3046e6aee
commit 273ca3de77
4 changed files with 37 additions and 9 deletions

View File

@ -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, EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, aSize, aStyle,
aFrameName, schIUScale ), aFrameName, schIUScale ),
m_base_frame_defaults( nullptr, "base_Frame_defaults" ), m_base_frame_defaults( nullptr, "base_Frame_defaults" ),
m_selectionFilterPanel( nullptr ) m_selectionFilterPanel( nullptr ),
m_inSymChangeTimerEvent( false )
{ {
if( ( aStyle & wxFRAME_NO_TASKBAR ) == 0 ) if( ( aStyle & wxFRAME_NO_TASKBAR ) == 0 )
createCanvas(); createCanvas();
@ -765,6 +766,12 @@ void SCH_BASE_FRAME::OnSymChangeDebounceTimer( wxTimerEvent& aEvent )
return; return;
} }
if( m_inSymChangeTimerEvent )
{
wxLogTrace( "KICAD_LIB_WATCH", "Restarting debounce timer" );
m_watcherDebounceTimer.StartOnce( 3000 );
}
wxLogTrace( "KICAD_LIB_WATCH", "OnSymChangeDebounceTimer" ); wxLogTrace( "KICAD_LIB_WATCH", "OnSymChangeDebounceTimer" );
// Disable logging to avoid spurious messages and check if the file has changed // 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_watcherLastModified = lastModified;
m_inSymChangeTimerEvent = true;
if( !GetScreen()->IsContentModified() if( !GetScreen()->IsContentModified()
|| IsOK( this, _( "The library containing the current symbol has changed.\n" || IsOK( this, _( "The library containing the current symbol has changed.\n"
"Do you want to reload the library?" ) ) ) "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_VIEWER, MAIL_REFRESH_SYMBOL, libName );
Kiway().ExpressMail( FRAME_SCH_SYMBOL_EDITOR, MAIL_REFRESH_SYMBOL, libName ); Kiway().ExpressMail( FRAME_SCH_SYMBOL_EDITOR, MAIL_REFRESH_SYMBOL, libName );
} }
m_inSymChangeTimerEvent = false;
} }

View File

@ -308,6 +308,7 @@ private:
wxFileName m_watcherFileName; wxFileName m_watcherFileName;
wxDateTime m_watcherLastModified; wxDateTime m_watcherLastModified;
wxTimer m_watcherDebounceTimer; wxTimer m_watcherDebounceTimer;
bool m_inSymChangeTimerEvent;
std::unique_ptr<NL_SCHEMATIC_PLUGIN> m_spaceMouse; std::unique_ptr<NL_SCHEMATIC_PLUGIN> m_spaceMouse;
}; };

View File

@ -435,12 +435,13 @@ protected:
PCB_ORIGIN_TRANSFORMS m_originTransforms; PCB_ORIGIN_TRANSFORMS m_originTransforms;
private: private:
std::unique_ptr<NL_PCBNEW_PLUGIN> m_spaceMouse; std::unique_ptr<NL_PCBNEW_PLUGIN> m_spaceMouse;
std::unique_ptr<wxFileSystemWatcher> m_watcher; std::unique_ptr<wxFileSystemWatcher> m_watcher;
wxFileName m_watcherFileName; wxFileName m_watcherFileName;
wxDateTime m_watcherLastModified; wxDateTime m_watcherLastModified;
wxTimer m_watcherDebounceTimer; wxTimer m_watcherDebounceTimer;
bool m_inFpChangeTimerEvent;
std::vector<wxEvtHandler*> m_boardChangeListeners; std::vector<wxEvtHandler*> m_boardChangeListeners;
}; };

View File

@ -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, EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName,
pcbIUScale ), pcbIUScale ),
m_pcb( nullptr ), m_pcb( nullptr ),
m_originTransforms( *this ) m_originTransforms( *this ),
m_inFpChangeTimerEvent( false )
{ {
m_watcherDebounceTimer.Bind( wxEVT_TIMER, &PCB_BASE_FRAME::OnFpChangeDebounceTimer, this ); 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 ) 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" ); wxLogTrace( "KICAD_LIB_WATCH", "OnFpChangeDebounceTimer" );
// Disable logging to avoid spurious messages and check if the file has changed // 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 ) if( !fp || !tbl )
return; return;
m_inFpChangeTimerEvent = true;
if( !GetScreen()->IsContentModified() if( !GetScreen()->IsContentModified()
|| IsOK( this, _( "The library containing the current footprint has changed.\n" || IsOK( this, _( "The library containing the current footprint has changed.\n"
"Do you want to reload the footprint?" ) ) ) "Do you want to reload the footprint?" ) ) )
@ -1220,9 +1235,7 @@ void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent )
std::vector<KIID> selectedItems; std::vector<KIID> selectedItems;
for( const EDA_ITEM* item : GetCurrentSelection() ) for( const EDA_ITEM* item : GetCurrentSelection() )
{
selectedItems.emplace_back( item->m_Uuid ); selectedItems.emplace_back( item->m_Uuid );
}
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
@ -1250,4 +1263,6 @@ void PCB_BASE_FRAME::OnFpChangeDebounceTimer( wxTimerEvent& aEvent )
DisplayError( this, ioe.What() ); DisplayError( this, ioe.What() );
} }
} }
m_inFpChangeTimerEvent = false;
} }