mirror of https://github.com/KLayout/klayout.git
Avoid memory corruption
The tiling processor now holds it's receivers in tl::shared_ptr. This prevents memory corruption and allows managing receiver lifetime externally.
This commit is contained in:
parent
5130950f14
commit
487545bbaa
|
|
@ -573,9 +573,6 @@ TilingProcessor::input (const std::string &name, const db::RecursiveShapeIterato
|
|||
|
||||
TilingProcessor::~TilingProcessor ()
|
||||
{
|
||||
for (std::vector<OutputSpec>::const_iterator o = m_outputs.begin (); o != m_outputs.end (); ++o) {
|
||||
delete o->receiver;
|
||||
}
|
||||
m_outputs.clear ();
|
||||
}
|
||||
|
||||
|
|
@ -727,7 +724,7 @@ TilingProcessor::receiver (const std::vector<tl::Variant> &args)
|
|||
|
||||
// Create another variable with a reference to the receiver object
|
||||
const tl::VariantUserClassBase *var_cls = gsi::cls_decl<TileOutputReceiver> ()->var_cls (true /*const*/);
|
||||
return tl::Variant (m_outputs[index].receiver, var_cls, false);
|
||||
return tl::Variant (m_outputs[index].receiver.get (), var_cls, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -869,9 +866,11 @@ TilingProcessor::execute (const std::string &desc)
|
|||
|
||||
try {
|
||||
|
||||
for (std::vector<OutputSpec>::const_iterator o = m_outputs.begin (); o != m_outputs.end (); ++o) {
|
||||
o->receiver->set_processor (this);
|
||||
o->receiver->begin (ntiles_w, ntiles_h, db::DPoint (l, b), tile_width, tile_height, frame);
|
||||
for (std::vector<OutputSpec>::iterator o = m_outputs.begin (); o != m_outputs.end (); ++o) {
|
||||
if (o->receiver) {
|
||||
o->receiver->set_processor (this);
|
||||
o->receiver->begin (ntiles_w, ntiles_h, db::DPoint (l, b), tile_width, tile_height, frame);
|
||||
}
|
||||
}
|
||||
|
||||
job.start ();
|
||||
|
|
@ -881,15 +880,19 @@ TilingProcessor::execute (const std::string &desc)
|
|||
job.wait (100);
|
||||
}
|
||||
|
||||
for (std::vector<OutputSpec>::const_iterator o = m_outputs.begin (); o != m_outputs.end (); ++o) {
|
||||
o->receiver->finish (!job.has_error ());
|
||||
o->receiver->set_processor (0);
|
||||
for (std::vector<OutputSpec>::iterator o = m_outputs.begin (); o != m_outputs.end (); ++o) {
|
||||
if (o->receiver) {
|
||||
o->receiver->finish (!job.has_error ());
|
||||
o->receiver->set_processor (0);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (...) {
|
||||
for (std::vector<OutputSpec>::const_iterator o = m_outputs.begin (); o != m_outputs.end (); ++o) {
|
||||
o->receiver->finish (false);
|
||||
o->receiver->set_processor (0);
|
||||
for (std::vector<OutputSpec>::iterator o = m_outputs.begin (); o != m_outputs.end (); ++o) {
|
||||
if (o->receiver) {
|
||||
o->receiver->finish (false);
|
||||
o->receiver->set_processor (0);
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class TilingProcessor;
|
|||
* @brief A receiver for the output data
|
||||
*/
|
||||
class DB_PUBLIC TileOutputReceiver
|
||||
: public gsi::ObjectBase
|
||||
: public gsi::ObjectBase, public tl::Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
|
@ -623,6 +623,7 @@ private:
|
|||
|
||||
struct InputSpec
|
||||
{
|
||||
InputSpec () : region (false), merged_semantics (false) { }
|
||||
std::string name;
|
||||
db::RecursiveShapeIterator iter;
|
||||
db::ICplxTrans trans;
|
||||
|
|
@ -632,9 +633,10 @@ private:
|
|||
|
||||
struct OutputSpec
|
||||
{
|
||||
OutputSpec () : id (0) { }
|
||||
std::string name;
|
||||
size_t id;
|
||||
db::TileOutputReceiver *receiver;
|
||||
tl::shared_ptr<db::TileOutputReceiver> receiver;
|
||||
db::ICplxTrans trans;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ gsi::Class<TileOutputReceiver_Impl> decl_TileOutputReceiver (decl_TileOutputRece
|
|||
|
||||
static void tp_output (db::TilingProcessor *proc, const std::string &name, db::TileOutputReceiver *rec)
|
||||
{
|
||||
rec->keep ();
|
||||
rec->gsi::ObjectBase::keep ();
|
||||
proc->output (name, 0, rec, db::ICplxTrans ());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue