13
0

Yet another attempt at fixing #9361

This commit is contained in:
Robin Gareus 2023-06-10 01:38:26 +02:00
parent 3fbc89e4ee
commit bb54bc0d40
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 34 additions and 17 deletions

View File

@ -511,6 +511,7 @@ private:
void trim_to_internal (timepos_t const & position, timecnt_t const & length); void trim_to_internal (timepos_t const & position, timecnt_t const & length);
void maybe_uncopy (); void maybe_uncopy ();
void subscribe_to_source_drop ();
bool verify_start (timepos_t const &); bool verify_start (timepos_t const &);
bool verify_length (timecnt_t&); bool verify_length (timecnt_t&);
@ -546,7 +547,9 @@ private:
void use_sources (SourceList const &); void use_sources (SourceList const &);
std::atomic<int> _source_deleted; std::atomic<int> _source_deleted;
Glib::Threads::Mutex _source_list_lock;
PBD::ScopedConnectionList _source_deleted_connections;
}; };
} /* namespace ARDOUR */ } /* namespace ARDOUR */

View File

@ -1559,12 +1559,12 @@ Region::source_deleted (std::weak_ptr<Source>)
if (!_session.deletion_in_progress()) { if (!_session.deletion_in_progress()) {
/* this is a very special case: at least one of the region's /* this is a very special case: at least one of the region's
sources has bee deleted, so invalidate all references to * sources has been deleted, so invalidate all references to
ourselves. Do NOT do this during session deletion, because * ourselves. We run the risk that this will actually result
then we run the risk that this will actually result * in this object being deleted (as refcnt goes to zero)
in this object being deleted (as refcnt goes to zero) * while emitting DropReferences.
while emitting DropReferences. */
*/ std::shared_ptr<Region> me (shared_from_this ());
drop_references (); drop_references ();
} }
@ -1586,6 +1586,7 @@ Region::master_source_names ()
void void
Region::set_master_sources (const SourceList& srcs) Region::set_master_sources (const SourceList& srcs)
{ {
Glib::Threads::Mutex::Lock lx (_source_list_lock);
for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) { for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
(*i)->dec_use_count (); (*i)->dec_use_count ();
} }
@ -1596,6 +1597,7 @@ Region::set_master_sources (const SourceList& srcs)
for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) { for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
(*i)->inc_use_count (); (*i)->inc_use_count ();
} }
subscribe_to_source_drop ();
} }
bool bool
@ -1944,6 +1946,7 @@ Region::rename_cue_marker (CueMarker& cm, std::string const & str)
void void
Region::drop_sources () Region::drop_sources ()
{ {
Glib::Threads::Mutex::Lock lx (_source_list_lock);
for (SourceList::const_iterator i = _sources.begin (); i != _sources.end(); ++i) { for (SourceList::const_iterator i = _sources.begin (); i != _sources.end(); ++i) {
(*i)->dec_use_count (); (*i)->dec_use_count ();
} }
@ -1955,27 +1958,38 @@ Region::drop_sources ()
} }
_master_sources.clear (); _master_sources.clear ();
_source_deleted_connections.drop_connections ();
} }
void void
Region::use_sources (SourceList const & s) Region::use_sources (SourceList const & s)
{ {
_source_deleted.store (0); Glib::Threads::Mutex::Lock lx (_source_list_lock);
set<std::shared_ptr<Source> > unique_srcs;
for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) { for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) {
_sources.push_back (*i); _sources.push_back (*i);
(*i)->inc_use_count (); (*i)->inc_use_count ();
_master_sources.push_back (*i); _master_sources.push_back (*i);
(*i)->inc_use_count (); (*i)->inc_use_count ();
}
subscribe_to_source_drop ();
}
/* connect only once to DropReferences, even if sources are replicated void
*/ Region::subscribe_to_source_drop ()
{
if (unique_srcs.find (*i) == unique_srcs.end ()) { _source_deleted.store (0);
unique_srcs.insert (*i); _source_deleted_connections.drop_connections ();
(*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, std::weak_ptr<Source>(*i))); set<std::shared_ptr<Source> > unique_srcs;
for (auto const& i : _sources) {
if (unique_srcs.find (i) == unique_srcs.end ()) {
unique_srcs.insert (i);
i->DropReferences.connect_same_thread (_source_deleted_connections, boost::bind (&Region::source_deleted, this, std::weak_ptr<Source>(i)));
}
}
for (auto const& i : _master_sources) {
if (unique_srcs.find (i) == unique_srcs.end ()) {
unique_srcs.insert (i);
i->DropReferences.connect_same_thread (_source_deleted_connections, boost::bind (&Region::source_deleted, this, std::weak_ptr<Source>(i)));
} }
} }
} }