diff options
author | Carl Hetherington <carl@carlh.net> | 2010-04-14 23:58:20 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2010-04-14 23:58:20 +0000 |
commit | 84e92060fd0593adcd47c39b358048715ece9c7a (patch) | |
tree | ce22806736ff7f7fc5f47dfd029f9d8a2b758a13 /libs | |
parent | 7939dd9399e8e86b579bbddeba73d997ec6cf1b7 (diff) |
Prevent crash in pool destruction during session teardown.
git-svn-id: svn://localhost/ardour2/branches/3.0@6905 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/butler.h | 1 | ||||
-rw-r--r-- | libs/ardour/butler.cc | 7 | ||||
-rw-r--r-- | libs/ardour/session.cc | 1 | ||||
-rw-r--r-- | libs/pbd/pbd/pool.h | 9 | ||||
-rw-r--r-- | libs/pbd/pool.cc | 10 |
5 files changed, 22 insertions, 6 deletions
diff --git a/libs/ardour/ardour/butler.h b/libs/ardour/ardour/butler.h index e9e832783b..e3760a8c53 100644 --- a/libs/ardour/ardour/butler.h +++ b/libs/ardour/ardour/butler.h @@ -49,6 +49,7 @@ class Butler : public SessionHandleRef void stop(); void wait_until_finished(); bool transport_work_requested() const; + void drop_references (); float read_data_rate() const; ///< in usec float write_data_rate() const; diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc index 8b88197073..b201960e0e 100644 --- a/libs/ardour/butler.cc +++ b/libs/ardour/butler.cc @@ -428,5 +428,12 @@ Butler::empty_pool_trash () } } +void +Butler::drop_references () +{ + SessionEvent::pool->set_trash (0); +} + + } // namespace ARDOUR diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index ac8d5d030f..11832646c8 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -229,6 +229,7 @@ Session::destroy () Stateful::loading_state_version = 0; + _butler->drop_references (); delete _butler; delete midi_control_ui; diff --git a/libs/pbd/pbd/pool.h b/libs/pbd/pbd/pool.h index 2d6111a4a3..ab06343b4a 100644 --- a/libs/pbd/pbd/pool.h +++ b/libs/pbd/pbd/pool.h @@ -111,10 +111,7 @@ class PerThreadPool void create_per_thread_pool (std::string name, unsigned long item_size, unsigned long nitems); CrossThreadPool* per_thread_pool (); - void set_trash (RingBuffer<CrossThreadPool*>* t) { - _trash = t; - } - + void set_trash (RingBuffer<CrossThreadPool*>* t); void add_to_trash (CrossThreadPool *); private: @@ -122,8 +119,10 @@ class PerThreadPool std::string _name; unsigned long _item_size; unsigned long _nitems; + + /** mutex to protect either changes to the _trash variable, or writes to the RingBuffer */ + Glib::Mutex _trash_mutex; RingBuffer<CrossThreadPool*>* _trash; - Glib::Mutex _trash_write_mutex; }; #endif // __qm_pool_h__ diff --git a/libs/pbd/pool.cc b/libs/pbd/pool.cc index 7859408c45..abb8695c23 100644 --- a/libs/pbd/pool.cc +++ b/libs/pbd/pool.cc @@ -198,10 +198,19 @@ PerThreadPool::per_thread_pool () return p; } +void +PerThreadPool::set_trash (RingBuffer<CrossThreadPool*>* t) +{ + Glib::Mutex::Lock lm (_trash_mutex); + _trash = t; +} + /** Add a CrossThreadPool to our trash, if we have one. If not, a warning is emitted. */ void PerThreadPool::add_to_trash (CrossThreadPool* p) { + Glib::Mutex::Lock lm (_trash_mutex); + if (!_trash) { warning << "Pool " << p->name() << " has no trash collector; a memory leak has therefore occurred" << endmsg; return; @@ -211,7 +220,6 @@ PerThreadPool::add_to_trash (CrossThreadPool* p) can only be one writer to the _trash RingBuffer) */ - Glib::Mutex::Lock lm (_trash_write_mutex); _trash->write (&p, 1); } |