Thread safety for new caches (which are also used during zone fill).

Fixes https://gitlab.com/kicad/code/kicad/issues/7749
This commit is contained in:
Jeff Young 2021-02-27 21:33:05 +00:00
parent 790e97a398
commit 3538c8a963
2 changed files with 18 additions and 6 deletions

View File

@ -271,8 +271,13 @@ public:
void IncrementTimeStamp() void IncrementTimeStamp()
{ {
m_timeStamp++; m_timeStamp++;
m_InsideAreaCache.clear();
m_InsideCourtyardCache.clear(); {
std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
m_InsideAreaCache.clear();
m_InsideCourtyardCache.clear();
}
m_CopperZoneRTrees.clear(); m_CopperZoneRTrees.clear();
} }
@ -1142,6 +1147,7 @@ public:
public: public:
// ------------ Run-time caches ------------- // ------------ Run-time caches -------------
std::mutex m_CachesMutex;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool > m_InsideCourtyardCache; std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool > m_InsideCourtyardCache;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool > m_InsideAreaCache; std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool > m_InsideAreaCache;

View File

@ -200,8 +200,9 @@ static void insideCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
if( !footprint ) if( !footprint )
return false; return false;
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
std::pair<BOARD_ITEM*, BOARD_ITEM*> key( footprint, item ); std::pair<BOARD_ITEM*, BOARD_ITEM*> key( footprint, item );
auto i = board->m_InsideCourtyardCache.find( key ); auto i = board->m_InsideCourtyardCache.find( key );
if( i != board->m_InsideCourtyardCache.end() ) if( i != board->m_InsideCourtyardCache.end() )
return i->second; return i->second;
@ -347,7 +348,11 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T ) if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
{ {
ZONE* itemZone = static_cast<ZONE*>( item ); ZONE* itemZone = static_cast<ZONE*>( item );
if( !itemZone->IsFilled() )
return false;
DRC_RTREE* itemRTree = board->m_CopperZoneRTrees[ itemZone ].get(); DRC_RTREE* itemRTree = board->m_CopperZoneRTrees[ itemZone ].get();
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
@ -376,15 +381,16 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
if( !zone || zone == item || zone->GetParent() == item ) if( !zone || zone == item || zone->GetParent() == item )
return false; return false;
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
std::pair<BOARD_ITEM*, BOARD_ITEM*> key( zone, item ); std::pair<BOARD_ITEM*, BOARD_ITEM*> key( zone, item );
auto i = board->m_InsideAreaCache.find( key ); auto i = board->m_InsideAreaCache.find( key );
if( i != board->m_InsideAreaCache.end() ) if( i != board->m_InsideAreaCache.end() )
return i->second; return i->second;
bool result = realInsideZone( zone ); bool result = realInsideZone( zone );
board->m_InsideCourtyardCache[ key ] = result; board->m_InsideAreaCache[ key ] = result;
return result; return result;
}; };