From 078e652859238e425baca5a8bb5c7da8ad05086d Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 4 May 2022 02:10:46 +0200 Subject: [PATCH] Implement rt-safe deletion - delegate to butler --- libs/ardour/ardour/butler.h | 8 ++++++ libs/ardour/ardour/rt_safe_delete.h | 39 +++++++++++++++++++++++++++++ libs/ardour/butler.cc | 11 ++++++++ libs/ardour/session.cc | 1 + 4 files changed, 59 insertions(+) create mode 100644 libs/ardour/ardour/rt_safe_delete.h diff --git a/libs/ardour/ardour/butler.h b/libs/ardour/ardour/butler.h index b6b11b4633..67e9818b6f 100644 --- a/libs/ardour/ardour/butler.h +++ b/libs/ardour/ardour/butler.h @@ -31,6 +31,7 @@ #include "pbd/g_atomic_compat.h" #include "pbd/pool.h" #include "pbd/ringbuffer.h" +#include "pbd/mpmc_queue.h" #include "ardour/libardour_visibility.h" #include "ardour/session_handle.h" @@ -62,6 +63,11 @@ public: void map_parameters (); + bool delegate (sigc::slot const& work) { + bool rv = _delegated_work.push_back (work); + summon (); + return rv; + } samplecnt_t audio_capture_buffer_size () const { return _audio_capture_buffer_size; @@ -92,6 +98,7 @@ private: void* thread_work (); void empty_pool_trash (); + void process_delegated_work (); void config_changed (std::string); bool flush_tracks_to_disk_normal (boost::shared_ptr, uint32_t& errors); void queue_request (Request::Type r); @@ -109,6 +116,7 @@ private: PBD::RingBuffer pool_trash; CrossThreadChannel _xthread; + PBD::MPMCQueue > _delegated_work; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/rt_safe_delete.h b/libs/ardour/ardour/rt_safe_delete.h new file mode 100644 index 0000000000..f848ea155f --- /dev/null +++ b/libs/ardour/ardour/rt_safe_delete.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 Robin Gareus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include "ardour/audioengine.h" +#include "ardour/butler.h" +#include "ardour/session.h" + +namespace ARDOUR { + +template +void rt_safe_delete (ARDOUR::Session* s, C* gc) { + if (s->deletion_in_progress () || !s->engine ().in_process_thread ()) { + delete gc; + return; + } + if (!s->butler ()->delegate (sigc::bind ([] (C* p) { delete p; }, gc))) { + delete gc; + return; + } +} + +} diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc index f16b3a0d5a..3def1e7740 100644 --- a/libs/ardour/butler.cc +++ b/libs/ardour/butler.cc @@ -327,6 +327,7 @@ Butler::thread_work () DEBUG_TRACE (DEBUG::Butler, "butler emptying pool trash\n"); empty_pool_trash (); + process_delegated_work (); } return (0); @@ -464,11 +465,21 @@ Butler::empty_pool_trash () } } +void +Butler::process_delegated_work () +{ + sigc::slot sl; + while (_delegated_work.pop_front (sl)) { + sl (); + } +} + void Butler::drop_references () { std::cerr << "Butler drops pool trash\n"; SessionEvent::pool->set_trash (0); + process_delegated_work (); } } // namespace ARDOUR diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index b397ce90ab..bb546ab04b 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -104,6 +104,7 @@ #include "ardour/route_graph.h" #include "ardour/route_group.h" #include "ardour/rt_tasklist.h" +#include "ardour/rt_safe_delete.h" #include "ardour/silentfilesource.h" #include "ardour/send.h" #include "ardour/selection.h"