Protect against double-refresh

The wxtimer can fire multiple times and there exists the possiblity for
this to happen before the flags are properly set to prevent it.  This
creates a concurrency mutex to skip the EDA_DRAW_PANEL_GAL refresh if
one is already underway.

Fixes https://gitlab.com/kicad/code/kicad/issues/12094
This commit is contained in:
Seth Hillbrand 2022-07-27 20:26:39 -07:00
parent 120ceade06
commit 39dd51490d
2 changed files with 8 additions and 0 deletions

View File

@ -174,6 +174,11 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
void EDA_DRAW_PANEL_GAL::DoRePaint() void EDA_DRAW_PANEL_GAL::DoRePaint()
{ {
if( !m_refreshMutex.try_lock() )
return;
std::lock_guard<std::mutex> lock( m_refreshMutex, std::adopt_lock );
// Repaint the canvas, and fix scrollbar cursors // Repaint the canvas, and fix scrollbar cursors
// Usually called by a OnPaint event, but because it does not use a wxPaintDC, // Usually called by a OnPaint event, but because it does not use a wxPaintDC,
// it can be called outside a wxPaintEvent. // it can be called outside a wxPaintEvent.

View File

@ -35,6 +35,7 @@
#include <math/vector2d.h> #include <math/vector2d.h>
#include <widgets/msgpanel.h> #include <widgets/msgpanel.h>
#include <memory> #include <memory>
#include <mutex>
#include <gal/cursors.h> #include <gal/cursors.h>
@ -253,6 +254,8 @@ protected:
bool m_pendingRefresh; ///< Is there a redraw event requested? bool m_pendingRefresh; ///< Is there a redraw event requested?
wxTimer m_refreshTimer; ///< Timer to prevent too-frequent refreshing wxTimer m_refreshTimer; ///< Timer to prevent too-frequent refreshing
std::mutex m_refreshMutex; ///< Blocks multiple calls to the draw
/// True if GAL is currently redrawing the view /// True if GAL is currently redrawing the view
bool m_drawing; bool m_drawing;