Finally found the intermittant QA crash
When loading footprints/zones in parallel, we cannot reference a static vector that gets cleared by other threads. It is unclear why this element was ever static to begin with (premature optimization?) but it has been this way for a long time. We never noticed until we threaded load cycles, which gave the hatch a chance to override itself and cause crashes Fixes https://gitlab.com/kicad/code/kicad/issues/9888
This commit is contained in:
parent
aa9fa09000
commit
8218f9ab44
|
@ -905,54 +905,25 @@ void ZONE::HatchBorder()
|
||||||
min_a += offset;
|
min_a += offset;
|
||||||
|
|
||||||
// loop through hatch lines
|
// loop through hatch lines
|
||||||
#define MAXPTS 200 // Usually we store only few values per one hatch line
|
std::vector<VECTOR2I> pointbuffer;
|
||||||
// depending on the complexity of the zone outline
|
pointbuffer.reserve( 256 );
|
||||||
|
|
||||||
static std::vector<VECTOR2I> pointbuffer;
|
|
||||||
pointbuffer.clear();
|
|
||||||
pointbuffer.reserve( MAXPTS + 2 );
|
|
||||||
|
|
||||||
for( int a = min_a; a < max_a; a += spacing )
|
for( int a = min_a; a < max_a; a += spacing )
|
||||||
{
|
{
|
||||||
// get intersection points for this hatch line
|
|
||||||
|
|
||||||
// Note: because we should have an even number of intersections with the
|
|
||||||
// current hatch line and the zone outline (a closed polygon,
|
|
||||||
// or a set of closed polygons), if an odd count is found
|
|
||||||
// we skip this line (should not occur)
|
|
||||||
pointbuffer.clear();
|
pointbuffer.clear();
|
||||||
|
|
||||||
// Iterate through all vertices
|
// Iterate through all vertices
|
||||||
for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
|
for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
|
||||||
{
|
{
|
||||||
double x, y;
|
double x, y;
|
||||||
bool ok;
|
|
||||||
|
|
||||||
SEG segment = *iterator;
|
SEG segment = *iterator;
|
||||||
|
|
||||||
ok = FindLineSegmentIntersection( a, slope, segment.A.x, segment.A.y, segment.B.x,
|
if( FindLineSegmentIntersection( a, slope, segment.A.x, segment.A.y, segment.B.x,
|
||||||
segment.B.y, x, y );
|
segment.B.y, x, y ) )
|
||||||
|
pointbuffer.emplace_back( KiROUND( x ), KiROUND( y ) );
|
||||||
if( ok )
|
|
||||||
{
|
|
||||||
VECTOR2I point( KiROUND( x ), KiROUND( y ) );
|
|
||||||
pointbuffer.push_back( point );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pointbuffer.size() >= MAXPTS ) // overflow
|
|
||||||
{
|
|
||||||
wxASSERT( 0 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure we have found an even intersection points count
|
|
||||||
// because intersections are the ends of segments
|
|
||||||
// inside the polygon(s) and a segment has 2 ends.
|
|
||||||
// if not, this is a strange case (a bug ?) so skip this hatch
|
|
||||||
if( pointbuffer.size() % 2 != 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// sort points in order of descending x (if more than 2) to
|
// sort points in order of descending x (if more than 2) to
|
||||||
// ensure the starting point and the ending point of the same segment
|
// ensure the starting point and the ending point of the same segment
|
||||||
// are stored one just after the other.
|
// are stored one just after the other.
|
||||||
|
@ -960,7 +931,7 @@ void ZONE::HatchBorder()
|
||||||
sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
|
sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
|
||||||
|
|
||||||
// creates lines or short segments inside the complex polygon
|
// creates lines or short segments inside the complex polygon
|
||||||
for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
|
for( size_t ip = 0; ip + 1 < pointbuffer.size(); ip += 2 )
|
||||||
{
|
{
|
||||||
int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
|
int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue