pcbnew: more thread (and nested wx event loop) safety for the zone filling/connectivity algo

This commit is contained in:
Tomasz Włostowski 2017-12-14 23:49:46 +01:00
parent 87938b06b4
commit 75b21d010b
6 changed files with 74 additions and 3 deletions

56
include/core/lockable.h Normal file
View File

@ -0,0 +1,56 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 KiCad Developers, see change_log.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __LOCKABLE_H
#define __LOCKABLE_H
#include <thread>
#include <mutex>
class LOCKABLE
{
public:
LOCKABLE() {};
~LOCKABLE() {};
void Lock()
{
m_lock.lock();
}
void Unlock()
{
m_lock.unlock();
}
bool TryLock()
{
return m_lock.try_lock();
}
private:
std::mutex m_lock;
};
#endif

View File

@ -27,6 +27,7 @@
#define __CONNECTIVITY_DATA_H
#include <core/typeinfo.h>
#include <core/lockable.h>
#include <wx/string.h>
#include <vector>
@ -67,7 +68,7 @@ struct RN_DYNAMIC_LINE
};
// a wrapper class encompassing the connectivity computation algorithm and the
class CONNECTIVITY_DATA
class CONNECTIVITY_DATA : public LOCKABLE
{
public:
CONNECTIVITY_DATA();

View File

@ -96,6 +96,9 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
auto connectivity = m_Pcb->GetConnectivity();
if( !connectivity->TryLock() )
return;
COLOR4D color = Settings().Colors().GetItemColor( LAYER_RATSNEST );
for( int i = 1; i < connectivity->GetNetCount(); ++i )
@ -124,6 +127,8 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
}
}
}
connectivity->Unlock();
}

View File

@ -57,6 +57,9 @@ const BOX2I RATSNEST_VIEWITEM::ViewBBox() const
void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
{
if( !m_data->TryLock() )
return;
constexpr int CROSS_SIZE = 200000;
auto gal = aView->GetGAL();
@ -120,6 +123,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
}
}
}
m_data->Unlock();
}

View File

@ -86,6 +86,8 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
std::vector<CN_ZONE_ISOLATED_ISLAND_LIST> toFill;
auto connectivity = m_board->GetConnectivity();
connectivity->Lock();
// Remove segment zones
m_board->m_Zone.DeleteAll();
@ -220,7 +222,11 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
{
connectivity->Update( toFill[i].m_zone );
}
connectivity->RecalculateRatsnest();
}
connectivity->Unlock();
}

View File

@ -94,8 +94,6 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose )
{
std::vector<ZONE_CONTAINER*> toFill;
BOARD_COMMIT commit( this );
for( auto zone : GetBoard()->Zones() )
{
toFill.push_back(zone);