summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-04-28 21:37:18 +0200
committerRobin Gareus <robin@gareus.org>2016-04-28 21:37:18 +0200
commit17d782829e9321d5a1084851834356edd12a4bc3 (patch)
tree782c8c4f5bc395a7472689fc735a6ec81d8c1580 /libs
parent633f2189111be18cb03fe847707b0f598e453abe (diff)
flush pending Session Events at session close
This prevents a memory leak: The session is closed. The session-butler drops memory pool trash. The Engine keeps running. Once the AudioEngine is taken down (sample-rate switch, or at exit), the backend process-thread is terminated but there is no trash-can anymore. If there are unprocessed SessionEvents, this calls free_per_thread_pool() -> cp->parent()->add_to_trash (cp). "parent()" in this case the trash-can the butler emptied.
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/session.cc36
1 files changed, 36 insertions, 0 deletions
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index ef5ace53e8..68c7d3957f 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -745,6 +745,42 @@ Session::destroy ()
delete midi_clock;
delete _tempo_map;
+ /* clear event queue, the session is gone, nobody is interested in
+ * those anymore, but they do leak memory if not removed
+ */
+ while (!immediate_events.empty ()) {
+ Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ SessionEvent *ev = immediate_events.front ();
+ DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Drop event: %1\n", enum_2_string (ev->type)));
+ immediate_events.pop_front ();
+ bool remove = true;
+ bool del = true;
+ switch (ev->type) {
+ case SessionEvent::AutoLoop:
+ case SessionEvent::AutoLoopDeclick:
+ case SessionEvent::Skip:
+ case SessionEvent::PunchIn:
+ case SessionEvent::PunchOut:
+ case SessionEvent::StopOnce:
+ case SessionEvent::RangeStop:
+ case SessionEvent::RangeLocate:
+ remove = false;
+ del = false;
+ break;
+ case SessionEvent::RealTimeOperation:
+ process_rtop (ev);
+ del = false;
+ default:
+ break;
+ }
+ if (remove) {
+ del = del && !_remove_event (ev);
+ }
+ if (del) {
+ delete ev;
+ }
+ }
+
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS