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:
Matthias Koefferlein 2017-08-21 23:40:18 +02:00
parent 5130950f14
commit 487545bbaa
3 changed files with 21 additions and 16 deletions

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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 ());
}