Implement a safer (RAII) tool re-entrancy guard.

Fixes https://gitlab.com/kicad/code/kicad/issues/8873
This commit is contained in:
Jeff Young 2021-07-27 16:36:46 +01:00
parent 886dc2f43e
commit dd5676f4bc
4 changed files with 53 additions and 49 deletions

View File

@ -114,8 +114,8 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
if( m_inPlaceSymbol )
return 0;
else
m_inPlaceSymbol = true;
REENTRANCY_GUARD guard( &m_inPlaceSymbol );
if( aEvent.IsAction( &EE_ACTIONS::placeSymbol ) )
{
@ -361,7 +361,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
getViewControls()->SetAutoPan( false );
getViewControls()->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inPlaceSymbol = false;
return 0;
}
@ -374,8 +374,8 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
if( m_inPlaceImage )
return 0;
else
m_inPlaceImage = true;
REENTRANCY_GUARD guard( &m_inPlaceImage );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
getViewControls()->ShowCursor( true );
@ -580,7 +580,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
getViewControls()->SetAutoPan( false );
getViewControls()->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inPlaceImage = false;
return 0;
}
@ -597,6 +597,8 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
if( m_inSingleClickPlace )
return 0;
REENTRANCY_GUARD guard( &m_inSingleClickPlace );
if( type == SCH_JUNCTION_T && aEvent.HasPosition() )
{
EE_SELECTION& selection = m_selectionTool->GetSelection();
@ -656,8 +658,6 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
return 0;
}
m_inSingleClickPlace = true;
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
getViewControls()->ShowCursor( true );
@ -852,7 +852,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
controls->ForceCursorPosition( false );
m_inSingleClickPlace = false;
return 0;
}
@ -981,8 +981,8 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
if( m_inTwoClickPlace )
return 0;
else
m_inTwoClickPlace = true;
REENTRANCY_GUARD guard( &m_inTwoClickPlace );
bool isText = aEvent.IsAction( &EE_ACTIONS::placeSchematicText );
bool isGlobalLabel = aEvent.IsAction( &EE_ACTIONS::placeGlobalLabel );
@ -1234,7 +1234,6 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
controls->CaptureCursor( false );
controls->ForceCursorPosition( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inTwoClickPlace = false;
return 0;
}
@ -1245,8 +1244,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
if( m_inDrawSheet )
return 0;
else
m_inDrawSheet = true;
REENTRANCY_GUARD guard( &m_inDrawSheet );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
getViewControls()->ShowCursor( true );
@ -1416,7 +1415,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
getViewControls()->SetAutoPan( false );
getViewControls()->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inDrawSheet = false;
return 0;
}

View File

@ -34,6 +34,25 @@
class ACTION_MENU;
struct REENTRANCY_GUARD
{
REENTRANCY_GUARD( bool* aFlag ) :
m_flag( aFlag )
{
*m_flag = true;
}
~REENTRANCY_GUARD()
{
*m_flag = false;
}
private:
bool* m_flag;
};
class TOOL_INTERACTIVE : public TOOL_BASE
{
public:

View File

@ -917,8 +917,8 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
{
if( m_inPlaceFootprint )
return 0;
else
m_inPlaceFootprint = true;
REENTRANCY_GUARD guard( &m_inPlaceFootprint );
FOOTPRINT* fp = aEvent.Parameter<FOOTPRINT*>();
KIGFX::VIEW_CONTROLS* controls = getViewControls();
@ -1085,7 +1085,6 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
controls->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inPlaceFootprint = false;
return 0;
}
@ -1171,8 +1170,8 @@ int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
{
if( m_inPlaceTarget )
return 0;
else
m_inPlaceTarget = true;
REENTRANCY_GUARD guard( &m_inPlaceTarget );
KIGFX::VIEW* view = getView();
KIGFX::VIEW_CONTROLS* controls = getViewControls();
@ -1281,7 +1280,6 @@ int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inPlaceTarget = false;
return 0;
}

View File

@ -249,8 +249,8 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
PCB_SHAPE* line = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
@ -289,7 +289,6 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
line->SetFlags( IS_NEW );
}
m_inDrawingTool = false;
return 0;
}
@ -301,8 +300,8 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
PCB_SHAPE* rect = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
@ -341,7 +340,6 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
startingPoint = NULLOPT;
}
m_inDrawingTool = false;
return 0;
}
@ -353,8 +351,8 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
PCB_SHAPE* circle = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
@ -393,7 +391,6 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
startingPoint = NULLOPT;
}
m_inDrawingTool = false;
return 0;
}
@ -405,8 +402,8 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
PCB_SHAPE* arc = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
@ -440,7 +437,6 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
immediateMode = false;
}
m_inDrawingTool = false;
return 0;
}
@ -452,8 +448,8 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
BOARD_ITEM* text = nullptr;
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
@ -673,7 +669,6 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_frame->SetMsgPanel( board() );
m_inDrawingTool = false;
return 0;
}
@ -694,8 +689,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
enum DIMENSION_STEPS
{
@ -1121,7 +1116,6 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
m_view->Remove( &preview );
m_frame->SetMsgPanel( board() );
m_inDrawingTool = false;
return 0;
}
@ -1133,8 +1127,8 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
// Note: PlaceImportedGraphics() will convert PCB_SHAPE_T and PCB_TEXT_T to footprint
// items if needed
@ -1144,16 +1138,12 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
std::list<std::unique_ptr<EDA_ITEM>>& list = dlg.GetImportedItems();
if( dlgResult != wxID_OK )
{
m_inDrawingTool = false;
return 0;
}
// Ensure the list is not empty:
if( list.empty() )
{
wxMessageBox( _( "No graphic items found in file.") );
m_inDrawingTool = false;
return 0;
}
@ -1288,7 +1278,6 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inDrawingTool = false;
m_frame->PopTool( tool );
return 0;
@ -1304,8 +1293,8 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
if( m_inDrawingTool )
return 0;
else
m_inDrawingTool = true;
REENTRANCY_GUARD guard( &m_inDrawingTool );
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ANCHOR );
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
@ -1372,7 +1361,6 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inDrawingTool = false;
return 0;
}