Fixed issue #1993 ('with_area' modifies result of 'join')

Root cause was a held layout lock inside the TilingProcessor.
As that object was not always released inside the Ruby
DRC script, the lock was held sometimes longer than
needed and messed with the hierarchy system.
This commit is contained in:
Matthias Koefferlein 2025-03-03 01:05:04 +01:00
parent 5b4848ee50
commit 20111ce08d
9 changed files with 26 additions and 9 deletions

View File

@ -181,7 +181,7 @@ OriginalLayerEdgePairs::begin_iter () const
bool bool
OriginalLayerEdgePairs::empty () const OriginalLayerEdgePairs::empty () const
{ {
return m_iter.at_end (); return m_iter.at_end_no_lock ();
} }
const db::EdgePair * const db::EdgePair *

View File

@ -218,7 +218,7 @@ OriginalLayerEdges::begin_merged_iter () const
bool bool
OriginalLayerEdges::empty () const OriginalLayerEdges::empty () const
{ {
return m_iter.at_end (); return m_iter.at_end_no_lock ();
} }
bool bool

View File

@ -330,11 +330,7 @@ OriginalLayerRegion::begin_merged_iter () const
bool bool
OriginalLayerRegion::empty () const OriginalLayerRegion::empty () const
{ {
// NOTE: we should to make sure the iterator isn't validated as this would spoil the usability or OriginalLayerRegion upon return m_iter.at_end_no_lock ();
// layout changes
db::RecursiveShapeIterator iter = m_iter;
return iter.at_end ();
} }
bool bool

View File

@ -181,7 +181,7 @@ OriginalLayerTexts::begin_iter () const
bool bool
OriginalLayerTexts::empty () const OriginalLayerTexts::empty () const
{ {
return m_iter.at_end (); return m_iter.at_end_no_lock ();
} }
const db::Text * const db::Text *

View File

@ -598,6 +598,13 @@ RecursiveShapeIterator::at_end () const
return m_shape.at_end () || is_inactive (); return m_shape.at_end () || is_inactive ();
} }
bool
RecursiveShapeIterator::at_end_no_lock () const
{
RecursiveShapeIterator copy (*this);
return copy.at_end ();
}
std::vector<db::InstElement> std::vector<db::InstElement>
RecursiveShapeIterator::path () const RecursiveShapeIterator::path () const
{ {

View File

@ -709,6 +709,16 @@ public:
*/ */
bool at_end () const; bool at_end () const;
/**
* @brief End of iterator predicate
*
* Returns true, if the iterator is at the end of the sequence
*
* This version does not lock the layout and can be used after initialization
* to detect empty sequences.
*/
bool at_end_no_lock () const;
/** /**
* @brief Gets the translated property ID * @brief Gets the translated property ID
* *

View File

@ -876,7 +876,7 @@ TilingProcessor::execute (const std::string &desc)
if (tot_box.empty ()) { if (tot_box.empty ()) {
for (std::vector<InputSpec>::const_iterator i = m_inputs.begin (); i != m_inputs.end (); ++i) { for (std::vector<InputSpec>::const_iterator i = m_inputs.begin (); i != m_inputs.end (); ++i) {
if (! i->iter.at_end ()) { if (! i->iter.at_end_no_lock ()) {
if (scale_to_dbu ()) { if (scale_to_dbu ()) {
double dbu_value = i->iter.layout () ? i->iter.layout ()->dbu () : dbu (); double dbu_value = i->iter.layout () ? i->iter.layout ()->dbu () : dbu ();
tot_box += i->iter.bbox ().transformed (db::CplxTrans (dbu_value) * db::CplxTrans (i->trans)); tot_box += i->iter.bbox ().transformed (db::CplxTrans (dbu_value) * db::CplxTrans (i->trans));

View File

@ -148,7 +148,9 @@ TEST(2)
tp.queue ("_output(o1, _tile ? (i1 & i2 & _tile) : (i1 & i2), false)"); tp.queue ("_output(o1, _tile ? (i1 & i2 & _tile) : (i1 & i2), false)");
tp.queue ("!_tile && _output(o2, i1.outside(i2), false)"); tp.queue ("!_tile && _output(o2, i1.outside(i2), false)");
tp.queue ("_tile && _output(o3, _tile, false)"); tp.queue ("_tile && _output(o3, _tile, false)");
EXPECT_EQ (ly.under_construction (), false);
tp.execute ("test"); tp.execute ("test");
EXPECT_EQ (ly.under_construction (), false);
EXPECT_EQ (to_s (ly, top, o1), "box (60,10;70,20);box (10,10;30,30)"); EXPECT_EQ (to_s (ly, top, o1), "box (60,10;70,20);box (10,10;30,30)");
EXPECT_EQ (to_s (ly, top, o2), "box (50,40;80,70)"); EXPECT_EQ (to_s (ly, top, o2), "box (50,40;80,70)");

View File

@ -4624,6 +4624,8 @@ TP_SCRIPT
res res
end end
tp._destroy
DRCLayer::new(@engine, res) DRCLayer::new(@engine, res)
end end