tracing and small fixes to improve object destruction pathways
authorPaul Davis <paul@linuxaudiosystems.com>
Sat, 28 Nov 2009 00:49:04 +0000 (00:49 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sat, 28 Nov 2009 00:49:04 +0000 (00:49 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6195 d708f5d6-7413-0410-9779-e7cbd77b26cf

13 files changed:
libs/ardour/audio_diskstream.cc
libs/ardour/audio_playlist.cc
libs/ardour/audiofilesource.cc
libs/ardour/diskstream.cc
libs/ardour/playlist.cc
libs/ardour/region.cc
libs/ardour/region_factory.cc
libs/ardour/route.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/source.cc
libs/ardour/track.cc
libs/pbd/boost_debug.cc

index faa46847450a3a5c66fd0634c5660e72aacbc054..7ef971642d5f65a55d84c90db5c084be9cfc5bee 100644 (file)
@@ -49,6 +49,7 @@
 #include "ardour/butler.h"
 #include "ardour/configuration.h"
 #include "ardour/cycle_timer.h"
+#include "ardour/debug.h"
 #include "ardour/io.h"
 #include "ardour/playlist_factory.h"
 #include "ardour/region_factory.h"
@@ -122,7 +123,7 @@ AudioDiskstream::init (Diskstream::Flag f)
 
 AudioDiskstream::~AudioDiskstream ()
 {
-       cerr << "AD going away\n";
+       DEBUG_TRACE (DEBUG::Destruction, string_compose ("Audio Diskstream %1 destructor\n", _name));
 
        notify_callbacks ();
 
index eb4913e72778ab2f4e05991d93b0bc7b3ebf6642..30479cf65b2dc4df0d327670d53811bfec06f3c8 100644 (file)
@@ -351,7 +351,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
        boost::shared_ptr<AudioRegion> top;
        boost::shared_ptr<AudioRegion> bottom;
        boost::shared_ptr<Crossfade>   xfade;
-       RegionList*  touched_regions;
+       RegionList*  touched_regions = 0;
 
        if (in_set_state || in_partition) {
                return;
@@ -401,6 +401,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
 
                OverlapType c = top->coverage (bottom->position(), bottom->last_frame());
 
+               delete touched_regions;
+
                try {
                        switch (c) {
                        case OverlapNone:
@@ -509,6 +511,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
                }
 
        }
+
+       delete touched_regions;
 }
 
 void
index e9eb3641da88059b620a9c1836028526634f9979..f2f09b71fc8262e666d28f6382b2765e8154f90e 100644 (file)
@@ -45,6 +45,7 @@
 #include <glibmm/thread.h>
 
 #include "ardour/audiofilesource.h"
+#include "ardour/debug.h"
 #include "ardour/sndfile_helpers.h"
 #include "ardour/sndfilesource.h"
 #include "ardour/session.h"
@@ -99,7 +100,6 @@ AudioFileSource::AudioFileSource (Session& s, const ustring& path, bool embedded
        if (init (path, true)) {
                throw failed_constructor ();
        }
-       cerr << "AFS1 created, " << path << endl;
 }
 
 /** 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)) {
                throw failed_constructor ();
        }
-       cerr << "AFS2 created, " << path << endl;
 }
 
 /** 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)) {
                throw failed_constructor ();
        }
-       cerr << "AFS3 created, " << path() << endl;
 }
 
 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()) {
-               cerr << "\tremoving file\n";
                unlink (_path.c_str());
                unlink (peakpath.c_str());
        }
index b6cc9d6a04e8950ec19bd38c4002f993e4dc2760..e2dfc271002458fab5a588dd9c508cbeeb9c6094 100644 (file)
@@ -129,9 +129,11 @@ Diskstream::init (Flag f)
 
 Diskstream::~Diskstream ()
 {
-       if (_playlist)
-               _playlist->release ();
        DEBUG_TRACE (DEBUG::Destruction, string_compose ("Diskstream %1 deleted\n", _name));
+
+       if (_playlist) {
+               _playlist->release ();
+       }
 }
 
 void
index f57093ea40fa2fd542059310eb2d7f8b288d39a1..aa41bf65d167d75f642b9fe2f328d37ac3177c67 100644 (file)
@@ -32,6 +32,7 @@
 #include "pbd/xml++.h"
 #include "pbd/stacktrace.h"
 
+#include "ardour/debug.h"
 #include "ardour/playlist.h"
 #include "ardour/session.h"
 #include "ardour/region.h"
@@ -270,6 +271,7 @@ Playlist::init (bool hide)
 
 Playlist::~Playlist ()
 {
+       DEBUG_TRACE (DEBUG::Destruction, string_compose ("Playlist %1 destructor\n", _name));
        {
                RegionLock rl (this);
 
index c59a5bb562fa65d5829c03019c59b2a5c416b233..cbfd9a9b33e84a9bee373db855d26618cc3aa759 100644 (file)
@@ -339,9 +339,9 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
 
 Region::~Region ()
 {
+       DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this));
        notify_callbacks ();
        GoingAway (); /* EMIT SIGNAL */
-       DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 deleted\n", _name));
 }
 
 void
index 8b2d30d511cc485603958fc3db3d316018b67569..91cc2dbe2ac76b88f0a0c71a2c39f65e24caed7b 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include "pbd/error.h"
+#include "pbd/boost_debug.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) {
                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<Region> ret (boost::static_pointer_cast<Region> (arp));
                ret->unlock_property_changes ();
@@ -76,7 +78,9 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
        boost::shared_ptr<const MidiRegion> mr;
 
        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 ();
                /* pure copy constructor - no CheckNewRegion emitted */
                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) {
                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<Region> ret (boost::static_pointer_cast<Region> (arp));
                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) {
 
                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<Region> ret (boost::static_pointer_cast<Region> (arp));
                ret->unlock_property_changes ();
@@ -184,7 +190,9 @@ RegionFactory::create (SourceList& srcs, const XMLNode& node)
        }
 
        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 ();
                CheckNewRegion (ret);
                return ret;
@@ -205,7 +213,9 @@ RegionFactory::create (boost::shared_ptr<Source> src, nframes_t start, nframes_t
        boost::shared_ptr<MidiSource> ms;
 
        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 ();
                if (announce) {
                        CheckNewRegion (ret);
index 912e80c0ea5bf20fa951b5f098390c70e317fe65..1b8dfaec469a9f3ca98c237c2eecf43c69825474 100644 (file)
@@ -161,6 +161,7 @@ Route::init ()
 
 Route::~Route ()
 {
+       DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name));
        Metering::disconnect (_meter_connection);
 
        /* 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) {
                (*i)->drop_references ();
        }
+
        _processors.clear ();
 }
 
index 67f41a906f3656fc7e4598b1ea7f24f6e6cabac5..f7dfd2111d72b409dcb922cf8ac76d5013854d36 100644 (file)
@@ -400,7 +400,7 @@ Session::destroy ()
                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(); ) {
                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()));
                (*i)->drop_references ();
-               DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
+               
 
                i = tmp;
        }
 
+       DEBUG_TRACE (DEBUG::Destruction, "delete unused playlists\n");
        for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
                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()));
                (*i)->drop_references ();
-               DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %2\n", (*i).use_count()));
 
                i = tmp;
        }
@@ -437,24 +437,28 @@ Session::destroy ()
                tmp = i;
                ++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 ();
-               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;
        }
 
        regions.clear ();
 
        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);
                boost::shared_ptr<RouteList> r = writer.get_copy ();
                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()));
                        (*i)->drop_references ();
-                       DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
-                       debug_pointers.push_back ((*i).get());
                }
                r->clear ();
                /* writer goes out of scope and updates master */
@@ -468,7 +472,6 @@ Session::destroy ()
                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()));
                        (*i)->drop_references ();
-                       DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
                }
                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()));
                i->second->drop_references ();
-               DEBUG_TRACE(DEBUG::Destruction, string_compose ("\tpost-ref%1\n", i->second.use_count()));
 
                i = tmp;
        }
-       cerr << "Pre source clear, we have " << sources.size() << endl;
+
        sources.clear ();
-       cerr << "Post source clear, we have " << sources.size() << endl;
+
 
        DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
        for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
@@ -501,6 +503,8 @@ Session::destroy ()
        delete mmc;
 
        boost_debug_list_ptrs ();
+
+       DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
 }
 
 void
@@ -1520,8 +1524,6 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
 
        for (i = r->begin(); i != r->end(); ++i) {
 
-               cerr << "\n\n\n CLEAR FED BY for " << (*i)->name() << endl;
-
                (*i)->fed_by.clear ();
 
                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 {
                        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);
 
                        if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
@@ -3722,10 +3724,10 @@ void
 Session::graph_reordered ()
 {
        /* 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;
        }
 
index f53dd7106ecfb8415822df0bdecbdce7feee22a1..1664b0b9f91fc2ee687259015337fae65836e82c 100644 (file)
@@ -1405,7 +1405,7 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
        if (has_diskstream) {
                if (type == DataType::AUDIO) {
                        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);
                        return ret;
                } else {
index 10b7ead270d390d56ada6328c38fd33961b08b8a..790b7f6c3e9cb85f2698658f71cbf4bb6b1eee0f 100644 (file)
@@ -75,8 +75,8 @@ Source::Source (Session& s, const XMLNode& node)
 
 Source::~Source ()
 {
+       DEBUG_TRACE (DEBUG::Destruction, string_compose ("Source %1 destructor\n", _name));
        notify_callbacks ();
-       DEBUG_TRACE (DEBUG::Destruction, string_compose ("Source %1 deleted\n", _name));
 }
 
 
index ce208769f6c14a94e54469990e6e2c82cb6ef20b..01201d38e751e586b32049f64f47df7b903faa98 100644 (file)
@@ -24,6 +24,7 @@
 #include "ardour/audioplaylist.h"
 #include "ardour/audioregion.h"
 #include "ardour/audiosource.h"
+#include "ardour/debug.h"
 #include "ardour/delivery.h"
 #include "ardour/diskstream.h"
 #include "ardour/io_processor.h"
@@ -62,6 +63,7 @@ Track::Track (Session& sess, const XMLNode& node, DataType default_type)
 
 Track::~Track ()
 {
+       DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
 }
 
 void
index c9487197e111ffdeee6aa888229ef7a528fd029d..33e7bb3564bb3f8153d12fef3d383c6365f3c493 100644 (file)
@@ -142,6 +142,7 @@ boost_debug_shared_ptr_mark_interesting (void* ptr, const char* type)
        Glib::Mutex::Lock guard (the_lock);
        pair<void*,const char*> newpair (ptr, type);
        interesting_pointers.insert (newpair);
+       // cerr << "Interesting object @ " << ptr << " of type " << type << endl;
 }
 
 void
@@ -168,12 +169,13 @@ boost_debug_shared_ptr_destructor (void const *sp, void const *obj, int use_coun
 
        if (x != sptrs.end()) {
                sptrs.erase (x);
+               // cerr << "Removed sp for " << obj << " @ " << sp << endl;
        }
 }
+
 void
 boost_debug_shared_ptr_constructor (void const *sp, void const *obj, int use_count)
 {
-
        if (is_interesting_object (obj)) {
                Glib::Mutex::Lock guard (the_lock);
                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());
 
                sptrs.insert (newpair);
+               // cerr << "Stored constructor for " << obj << " @ " << sp << endl;
        }
 }
 
@@ -189,10 +192,15 @@ void
 boost_debug_list_ptrs ()
 {
        Glib::Mutex::Lock guard (the_lock);
-       for (PointerMap::iterator x = sptrs.begin(); x != sptrs.end(); ++x) {
-               cerr << "Shared ptr @ " << x->first << " history: "
-                    << *x->second
-                    << endl;
+
+       if (sptrs.empty()) {
+               cerr << "There are no dangling shared ptrs\n";
+       } else {
+               for (PointerMap::iterator x = sptrs.begin(); x != sptrs.end(); ++x) {
+                       cerr << "Shared ptr @ " << x->first << " history: "
+                            << *x->second
+                            << endl;
+               }
        }
 }