tracing and small fixes to improve object destruction pathways

git-svn-id: svn://localhost/ardour2/branches/3.0@6195 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-11-28 00:49:04 +00:00
parent c5db9a21b9
commit 51693a3a58
13 changed files with 67 additions and 37 deletions

View file

@ -49,6 +49,7 @@
#include "ardour/butler.h" #include "ardour/butler.h"
#include "ardour/configuration.h" #include "ardour/configuration.h"
#include "ardour/cycle_timer.h" #include "ardour/cycle_timer.h"
#include "ardour/debug.h"
#include "ardour/io.h" #include "ardour/io.h"
#include "ardour/playlist_factory.h" #include "ardour/playlist_factory.h"
#include "ardour/region_factory.h" #include "ardour/region_factory.h"
@ -122,7 +123,7 @@ AudioDiskstream::init (Diskstream::Flag f)
AudioDiskstream::~AudioDiskstream () AudioDiskstream::~AudioDiskstream ()
{ {
cerr << "AD going away\n"; DEBUG_TRACE (DEBUG::Destruction, string_compose ("Audio Diskstream %1 destructor\n", _name));
notify_callbacks (); notify_callbacks ();

View file

@ -351,7 +351,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
boost::shared_ptr<AudioRegion> top; boost::shared_ptr<AudioRegion> top;
boost::shared_ptr<AudioRegion> bottom; boost::shared_ptr<AudioRegion> bottom;
boost::shared_ptr<Crossfade> xfade; boost::shared_ptr<Crossfade> xfade;
RegionList* touched_regions; RegionList* touched_regions = 0;
if (in_set_state || in_partition) { if (in_set_state || in_partition) {
return; return;
@ -401,6 +401,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
OverlapType c = top->coverage (bottom->position(), bottom->last_frame()); OverlapType c = top->coverage (bottom->position(), bottom->last_frame());
delete touched_regions;
try { try {
switch (c) { switch (c) {
case OverlapNone: case OverlapNone:
@ -509,6 +511,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
} }
} }
delete touched_regions;
} }
void void

View file

@ -45,6 +45,7 @@
#include <glibmm/thread.h> #include <glibmm/thread.h>
#include "ardour/audiofilesource.h" #include "ardour/audiofilesource.h"
#include "ardour/debug.h"
#include "ardour/sndfile_helpers.h" #include "ardour/sndfile_helpers.h"
#include "ardour/sndfilesource.h" #include "ardour/sndfilesource.h"
#include "ardour/session.h" #include "ardour/session.h"
@ -99,7 +100,6 @@ AudioFileSource::AudioFileSource (Session& s, const ustring& path, bool embedded
if (init (path, true)) { if (init (path, true)) {
throw failed_constructor (); throw failed_constructor ();
} }
cerr << "AFS1 created, " << path << endl;
} }
/** Constructor used for new internal-to-session files. */ /** Constructor used for new internal-to-session files. */
@ -114,7 +114,6 @@ AudioFileSource::AudioFileSource (Session& s, const ustring& path, bool embedded
if (init (path, false)) { if (init (path, false)) {
throw failed_constructor (); throw failed_constructor ();
} }
cerr << "AFS2 created, " << path << endl;
} }
/** Constructor used for existing internal-to-session files. File must exist. */ /** Constructor used for existing internal-to-session files. File must exist. */
@ -130,14 +129,12 @@ AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exi
if (init (_name, must_exist)) { if (init (_name, must_exist)) {
throw failed_constructor (); throw failed_constructor ();
} }
cerr << "AFS3 created, " << path() << endl;
} }
AudioFileSource::~AudioFileSource () AudioFileSource::~AudioFileSource ()
{ {
cerr << "AFS " << _name << " destructor, path = " << path() << endl; DEBUG_TRACE (DEBUG::Destruction, string_compose ("AudioFileSource destructor %1, removable? %2\n", _path, removable()));
if (removable()) { if (removable()) {
cerr << "\tremoving file\n";
unlink (_path.c_str()); unlink (_path.c_str());
unlink (peakpath.c_str()); unlink (peakpath.c_str());
} }

View file

@ -129,9 +129,11 @@ Diskstream::init (Flag f)
Diskstream::~Diskstream () Diskstream::~Diskstream ()
{ {
if (_playlist)
_playlist->release ();
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Diskstream %1 deleted\n", _name)); DEBUG_TRACE (DEBUG::Destruction, string_compose ("Diskstream %1 deleted\n", _name));
if (_playlist) {
_playlist->release ();
}
} }
void void

View file

@ -32,6 +32,7 @@
#include "pbd/xml++.h" #include "pbd/xml++.h"
#include "pbd/stacktrace.h" #include "pbd/stacktrace.h"
#include "ardour/debug.h"
#include "ardour/playlist.h" #include "ardour/playlist.h"
#include "ardour/session.h" #include "ardour/session.h"
#include "ardour/region.h" #include "ardour/region.h"
@ -270,6 +271,7 @@ Playlist::init (bool hide)
Playlist::~Playlist () Playlist::~Playlist ()
{ {
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Playlist %1 destructor\n", _name));
{ {
RegionLock rl (this); RegionLock rl (this);

View file

@ -339,9 +339,9 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
Region::~Region () Region::~Region ()
{ {
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this));
notify_callbacks (); notify_callbacks ();
GoingAway (); /* EMIT SIGNAL */ GoingAway (); /* EMIT SIGNAL */
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 deleted\n", _name));
} }
void void

View file

@ -18,6 +18,7 @@
*/ */
#include "pbd/error.h" #include "pbd/error.h"
#include "pbd/boost_debug.h"
#include "ardour/session.h" #include "ardour/session.h"
@ -45,6 +46,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start,
if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) { if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
AudioRegion* ar = new AudioRegion (other_a, start, length, name, layer, flags); AudioRegion* ar = new AudioRegion (other_a, start, length, name, layer, flags);
boost_debug_shared_ptr_mark_interesting (ar, typeid (ar).name());
boost::shared_ptr<AudioRegion> arp (ar); boost::shared_ptr<AudioRegion> arp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
ret->unlock_property_changes (); ret->unlock_property_changes ();
@ -76,7 +78,9 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
boost::shared_ptr<const MidiRegion> mr; boost::shared_ptr<const MidiRegion> mr;
if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) { if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
boost::shared_ptr<Region> ret (new AudioRegion (ar)); AudioRegion* arn = new AudioRegion (ar);
boost_debug_shared_ptr_mark_interesting (arn, typeid (arn).name());
boost::shared_ptr<Region> ret (arn);
ret->unlock_property_changes (); ret->unlock_property_changes ();
/* pure copy constructor - no CheckNewRegion emitted */ /* pure copy constructor - no CheckNewRegion emitted */
return ret; return ret;
@ -114,6 +118,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) { if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(srcs.front()->timeline_position()), name, layer, flags); AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(srcs.front()->timeline_position()), name, layer, flags);
boost_debug_shared_ptr_mark_interesting (ar, typeid (ar).name());
boost::shared_ptr<AudioRegion> arp (ar); boost::shared_ptr<AudioRegion> arp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
ret->unlock_property_changes (); ret->unlock_property_changes ();
@ -152,6 +157,7 @@ RegionFactory::create (const SourceList& srcs, nframes_t start, nframes_t length
if (srcs[0]->type() == DataType::AUDIO) { if (srcs[0]->type() == DataType::AUDIO) {
AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags); AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags);
boost_debug_shared_ptr_mark_interesting (ar, typeid (ar).name());
boost::shared_ptr<AudioRegion> arp (ar); boost::shared_ptr<AudioRegion> arp (ar);
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
ret->unlock_property_changes (); ret->unlock_property_changes ();
@ -184,7 +190,9 @@ RegionFactory::create (SourceList& srcs, const XMLNode& node)
} }
if (srcs[0]->type() == DataType::AUDIO) { if (srcs[0]->type() == DataType::AUDIO) {
boost::shared_ptr<Region> ret (new AudioRegion (srcs, node)); AudioRegion* ar = new AudioRegion (srcs, node);
boost_debug_shared_ptr_mark_interesting (ar, typeid (ar).name());
boost::shared_ptr<Region> ret (ar);
ret->unlock_property_changes (); ret->unlock_property_changes ();
CheckNewRegion (ret); CheckNewRegion (ret);
return ret; return ret;
@ -205,7 +213,9 @@ RegionFactory::create (boost::shared_ptr<Source> src, nframes_t start, nframes_t
boost::shared_ptr<MidiSource> ms; boost::shared_ptr<MidiSource> ms;
if ((as = boost::dynamic_pointer_cast<AudioSource>(src)) != 0) { if ((as = boost::dynamic_pointer_cast<AudioSource>(src)) != 0) {
boost::shared_ptr<Region> ret (new AudioRegion (as, start, length, name, layer, flags)); AudioRegion* ar = new AudioRegion (as, start, length, name, layer, flags);
boost_debug_shared_ptr_mark_interesting (ar, typeid (ar).name());
boost::shared_ptr<Region> ret (ar);
ret->unlock_property_changes (); ret->unlock_property_changes ();
if (announce) { if (announce) {
CheckNewRegion (ret); CheckNewRegion (ret);

View file

@ -161,6 +161,7 @@ Route::init ()
Route::~Route () Route::~Route ()
{ {
DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name));
Metering::disconnect (_meter_connection); Metering::disconnect (_meter_connection);
/* don't use clear_processors here, as it depends on the session which may /* don't use clear_processors here, as it depends on the session which may
@ -170,6 +171,7 @@ Route::~Route ()
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
(*i)->drop_references (); (*i)->drop_references ();
} }
_processors.clear (); _processors.clear ();
} }

View file

@ -400,7 +400,7 @@ Session::destroy ()
i = tmp; i = tmp;
} }
DEBUG_TRACE (DEBUG::Destruction, "delete playlists\n"); DEBUG_TRACE (DEBUG::Destruction, "delete used playlists\n");
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) { for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
PlaylistList::iterator tmp; PlaylistList::iterator tmp;
@ -409,11 +409,12 @@ Session::destroy ()
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for used playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for used playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
(*i)->drop_references (); (*i)->drop_references ();
DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
i = tmp; i = tmp;
} }
DEBUG_TRACE (DEBUG::Destruction, "delete unused playlists\n");
for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) { for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
PlaylistList::iterator tmp; PlaylistList::iterator tmp;
@ -422,7 +423,6 @@ Session::destroy ()
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for unused playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for unused playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
(*i)->drop_references (); (*i)->drop_references ();
DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %2\n", (*i).use_count()));
i = tmp; i = tmp;
} }
@ -437,24 +437,28 @@ Session::destroy ()
tmp = i; tmp = i;
++tmp; ++tmp;
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count())); DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 (%2); pre-ref = %2\n", i->second->name(), i->second.get(), i->second.use_count()));
i->second->drop_references (); i->second->drop_references ();
DEBUG_TRACE(DEBUG::Destruction, string_compose ("\tpost-ref%2\n", i->second.use_count())); DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count()));
i = tmp; i = tmp;
} }
regions.clear (); regions.clear ();
DEBUG_TRACE (DEBUG::Destruction, "delete routes\n"); DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
/* reset these three references to special routes before we do the usual route delete thing */
auditioner.reset ();
_master_out.reset ();
_control_out.reset ();
{ {
RCUWriter<RouteList> writer (routes); RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> r = writer.get_copy (); boost::shared_ptr<RouteList> r = writer.get_copy ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
(*i)->drop_references (); (*i)->drop_references ();
DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
debug_pointers.push_back ((*i).get());
} }
r->clear (); r->clear ();
/* writer goes out of scope and updates master */ /* writer goes out of scope and updates master */
@ -468,7 +472,6 @@ Session::destroy ()
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
(*i)->drop_references (); (*i)->drop_references ();
DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
} }
dsl->clear (); dsl->clear ();
} }
@ -483,13 +486,12 @@ Session::destroy ()
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count())); DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
i->second->drop_references (); i->second->drop_references ();
DEBUG_TRACE(DEBUG::Destruction, string_compose ("\tpost-ref%1\n", i->second.use_count()));
i = tmp; i = tmp;
} }
cerr << "Pre source clear, we have " << sources.size() << endl;
sources.clear (); sources.clear ();
cerr << "Post source clear, we have " << sources.size() << endl;
DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n"); DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) { for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
@ -501,6 +503,8 @@ Session::destroy ()
delete mmc; delete mmc;
boost_debug_list_ptrs (); boost_debug_list_ptrs ();
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
} }
void void
@ -1520,8 +1524,6 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
for (i = r->begin(); i != r->end(); ++i) { for (i = r->begin(); i != r->end(); ++i) {
cerr << "\n\n\n CLEAR FED BY for " << (*i)->name() << endl;
(*i)->fed_by.clear (); (*i)->fed_by.clear ();
for (j = r->begin(); j != r->end(); ++j) { for (j = r->begin(); j != r->end(); ++j) {
@ -1785,7 +1787,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
try { try {
AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode); AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
boost_debug_shared_ptr_mark_interesting (at, typeid (at).name()); // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
track = boost::shared_ptr<AudioTrack>(at); track = boost::shared_ptr<AudioTrack>(at);
if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) { if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
@ -3722,10 +3724,10 @@ void
Session::graph_reordered () Session::graph_reordered ()
{ {
/* don't do this stuff if we are setting up connections /* don't do this stuff if we are setting up connections
from a set_state() call or creating new tracks. from a set_state() call or creating new tracks. Ditto for deletion.
*/ */
if (_state_of_the_state & InitialConnecting) { if (_state_of_the_state & (InitialConnecting|Deletion)) {
return; return;
} }

View file

@ -1405,7 +1405,7 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
if (has_diskstream) { if (has_diskstream) {
if (type == DataType::AUDIO) { if (type == DataType::AUDIO) {
AudioTrack* at = new AudioTrack (*this, node, version); AudioTrack* at = new AudioTrack (*this, node, version);
boost_debug_shared_ptr_mark_interesting (at, typeid (at).name()); // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
boost::shared_ptr<Route> ret (at); boost::shared_ptr<Route> ret (at);
return ret; return ret;
} else { } else {

View file

@ -75,8 +75,8 @@ Source::Source (Session& s, const XMLNode& node)
Source::~Source () Source::~Source ()
{ {
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Source %1 destructor\n", _name));
notify_callbacks (); notify_callbacks ();
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Source %1 deleted\n", _name));
} }

View file

@ -24,6 +24,7 @@
#include "ardour/audioplaylist.h" #include "ardour/audioplaylist.h"
#include "ardour/audioregion.h" #include "ardour/audioregion.h"
#include "ardour/audiosource.h" #include "ardour/audiosource.h"
#include "ardour/debug.h"
#include "ardour/delivery.h" #include "ardour/delivery.h"
#include "ardour/diskstream.h" #include "ardour/diskstream.h"
#include "ardour/io_processor.h" #include "ardour/io_processor.h"
@ -62,6 +63,7 @@ Track::Track (Session& sess, const XMLNode& node, DataType default_type)
Track::~Track () Track::~Track ()
{ {
DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
} }
void void

View file

@ -142,6 +142,7 @@ boost_debug_shared_ptr_mark_interesting (void* ptr, const char* type)
Glib::Mutex::Lock guard (the_lock); Glib::Mutex::Lock guard (the_lock);
pair<void*,const char*> newpair (ptr, type); pair<void*,const char*> newpair (ptr, type);
interesting_pointers.insert (newpair); interesting_pointers.insert (newpair);
// cerr << "Interesting object @ " << ptr << " of type " << type << endl;
} }
void void
@ -168,12 +169,13 @@ boost_debug_shared_ptr_destructor (void const *sp, void const *obj, int use_coun
if (x != sptrs.end()) { if (x != sptrs.end()) {
sptrs.erase (x); sptrs.erase (x);
// cerr << "Removed sp for " << obj << " @ " << sp << endl;
} }
} }
void void
boost_debug_shared_ptr_constructor (void const *sp, void const *obj, int use_count) boost_debug_shared_ptr_constructor (void const *sp, void const *obj, int use_count)
{ {
if (is_interesting_object (obj)) { if (is_interesting_object (obj)) {
Glib::Mutex::Lock guard (the_lock); Glib::Mutex::Lock guard (the_lock);
pair<void const*, SPDebug*> newpair; pair<void const*, SPDebug*> newpair;
@ -182,6 +184,7 @@ boost_debug_shared_ptr_constructor (void const *sp, void const *obj, int use_cou
newpair.second = new SPDebug (new Backtrace()); newpair.second = new SPDebug (new Backtrace());
sptrs.insert (newpair); sptrs.insert (newpair);
// cerr << "Stored constructor for " << obj << " @ " << sp << endl;
} }
} }
@ -189,11 +192,16 @@ void
boost_debug_list_ptrs () boost_debug_list_ptrs ()
{ {
Glib::Mutex::Lock guard (the_lock); Glib::Mutex::Lock guard (the_lock);
if (sptrs.empty()) {
cerr << "There are no dangling shared ptrs\n";
} else {
for (PointerMap::iterator x = sptrs.begin(); x != sptrs.end(); ++x) { for (PointerMap::iterator x = sptrs.begin(); x != sptrs.end(); ++x) {
cerr << "Shared ptr @ " << x->first << " history: " cerr << "Shared ptr @ " << x->first << " history: "
<< *x->second << *x->second
<< endl; << endl;
} }
}
} }
namespace boost { namespace boost {