From b1198f0842e6e4d6b1c01f07d91b42ef4a212788 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 12 Feb 2017 15:04:20 +0100 Subject: Use smart pointers to handle real-time memory disposal --- ingen/types.hpp | 6 ++++ src/server/BlockImpl.cpp | 7 ++-- src/server/BlockImpl.hpp | 23 +++++++------ src/server/BufferFactory.cpp | 6 ++++ src/server/BufferFactory.hpp | 6 +++- src/server/CompiledGraph.cpp | 10 +++--- src/server/CompiledGraph.hpp | 4 ++- src/server/DuplexPort.cpp | 6 ++-- src/server/DuplexPort.hpp | 4 +-- src/server/Engine.cpp | 2 +- src/server/Engine.hpp | 2 +- src/server/GraphImpl.cpp | 30 +++++++--------- src/server/GraphImpl.hpp | 27 ++++++++------- src/server/InputPort.cpp | 12 +++---- src/server/InputPort.hpp | 10 +++--- src/server/LV2Block.cpp | 40 +++++++++++----------- src/server/LV2Block.hpp | 34 ++++++++++++++----- src/server/NodeImpl.hpp | 4 +-- src/server/PortImpl.cpp | 31 ++++++----------- src/server/PortImpl.hpp | 68 +++++++++++++++++-------------------- src/server/PreProcessContext.hpp | 20 +++++++++-- src/server/events/Connect.cpp | 21 +++++------- src/server/events/Connect.hpp | 22 ++++++------ src/server/events/Copy.cpp | 8 ++--- src/server/events/Copy.hpp | 12 +++---- src/server/events/CreateBlock.cpp | 8 ++--- src/server/events/CreateBlock.hpp | 2 +- src/server/events/CreateGraph.cpp | 9 ++--- src/server/events/CreateGraph.hpp | 14 ++++---- src/server/events/CreatePort.cpp | 20 +++++------ src/server/events/CreatePort.hpp | 4 +-- src/server/events/Delete.cpp | 20 +++-------- src/server/events/Delete.hpp | 4 +-- src/server/events/Delta.cpp | 12 +++---- src/server/events/Delta.hpp | 2 +- src/server/events/Disconnect.cpp | 18 ++++------ src/server/events/Disconnect.hpp | 25 ++++++-------- src/server/events/DisconnectAll.cpp | 11 +++--- src/server/events/DisconnectAll.hpp | 16 ++++----- src/server/events/Mark.cpp | 10 +++--- src/server/events/Mark.hpp | 2 +- src/server/internals/BlockDelay.cpp | 2 +- src/server/internals/Controller.cpp | 2 +- src/server/internals/Note.cpp | 17 ++++------ src/server/internals/Note.hpp | 13 ++++--- src/server/internals/Time.cpp | 2 +- src/server/internals/Trigger.cpp | 2 +- wscript | 2 +- 48 files changed, 306 insertions(+), 326 deletions(-) diff --git a/ingen/types.hpp b/ingen/types.hpp index e6cbc3b5..d1055e22 100644 --- a/ingen/types.hpp +++ b/ingen/types.hpp @@ -19,6 +19,8 @@ #include +#include "raul/Maid.hpp" + namespace Ingen { #if __cplusplus >= 201103L @@ -27,9 +29,13 @@ using SPtr = std::shared_ptr; template using WPtr = std::weak_ptr; + +template +using MPtr = Raul::managed_ptr; #else #define SPtr std::shared_ptr #define WPtr std::weak_ptr +#define MPtr Raul::managed_ptr #endif template diff --git a/src/server/BlockImpl.cpp b/src/server/BlockImpl.cpp index d3a5b02d..bdcf1500 100644 --- a/src/server/BlockImpl.cpp +++ b/src/server/BlockImpl.cpp @@ -40,7 +40,6 @@ BlockImpl::BlockImpl(PluginImpl* plugin, SampleRate srate) : NodeImpl(plugin->uris(), parent, symbol) , _plugin(plugin) - , _ports(NULL) , _polyphony((polyphonic && parent) ? parent->internal_poly() : 1) , _mark(Mark::UNVISITED) , _polyphonic(polyphonic) @@ -60,8 +59,6 @@ BlockImpl::~BlockImpl() if (is_linked()) { parent_graph()->remove_block(*this); } - - delete _ports; } Node* @@ -120,7 +117,7 @@ BlockImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) } bool -BlockImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) +BlockImpl::apply_poly(RunContext& context, uint32_t poly) { if (!_polyphonic) poly = 1; @@ -129,7 +126,7 @@ BlockImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) if (_ports) for (uint32_t i = 0; i < num_ports(); ++i) - _ports->at(i)->apply_poly(context, maid, poly); + _ports->at(i)->apply_poly(context, poly); return true; } diff --git a/src/server/BlockImpl.hpp b/src/server/BlockImpl.hpp index 8f937dc5..2e3e5fcd 100644 --- a/src/server/BlockImpl.hpp +++ b/src/server/BlockImpl.hpp @@ -60,6 +60,8 @@ class BlockImpl : public NodeImpl , public boost::intrusive::slist_base_hook<> // In GraphImpl { public: + typedef Raul::Array Ports; + BlockImpl(PluginImpl* plugin, const Raul::Symbol& symbol, bool poly, @@ -152,8 +154,7 @@ public: virtual void set_polyphonic(bool p) { _polyphonic = p; } virtual bool prepare_poly(BufferFactory& bufs, uint32_t poly); - virtual bool apply_poly( - RunContext& context, Raul::Maid& maid, uint32_t poly); + virtual bool apply_poly(RunContext& context, uint32_t poly); /** Information about the Plugin this Block is an instance of. * Not the best name - not all blocks come from plugins (ie Graph) @@ -186,15 +187,15 @@ public: protected: PortImpl* nth_port_by_type(uint32_t n, bool input, PortType type); - PluginImpl* _plugin; - Raul::Array* _ports; ///< Access in audio thread only - uint32_t _polyphony; - std::set _providers; ///< Blocks connected to this one's input ports - std::set _dependants; ///< Blocks this one's output ports are connected to - Mark _mark; ///< Mark for graph compilation algorithm - bool _polyphonic; - bool _activated; - bool _enabled; + PluginImpl* _plugin; + MPtr _ports; ///< Access in audio thread only + uint32_t _polyphony; + std::set _providers; ///< Blocks connected to this one's input ports + std::set _dependants; ///< Blocks this one's output ports are connected to + Mark _mark; ///< Mark for graph compilation algorithm + bool _polyphonic; + bool _activated; + bool _enabled; }; } // namespace Server diff --git a/src/server/BufferFactory.cpp b/src/server/BufferFactory.cpp index 2fa98b67..fea74eca 100644 --- a/src/server/BufferFactory.cpp +++ b/src/server/BufferFactory.cpp @@ -52,6 +52,12 @@ BufferFactory::forge() return _engine.world()->forge(); } +Raul::Maid& +BufferFactory::maid() +{ + return *_engine.maid(); +} + void BufferFactory::free_list(Buffer* head) { diff --git a/src/server/BufferFactory.hpp b/src/server/BufferFactory.hpp index 09722b4e..8265fc98 100644 --- a/src/server/BufferFactory.hpp +++ b/src/server/BufferFactory.hpp @@ -32,6 +32,8 @@ #include "PortType.hpp" #include "types.hpp" +namespace Raul { class Maid; } + namespace Ingen { class URIs; @@ -71,7 +73,9 @@ public: void set_block_length(SampleCount block_length); void set_seq_size(uint32_t seq_size) { _seq_size = seq_size; } - Forge& forge(); + Forge& forge(); + Raul::Maid& maid(); + URIs& uris() { return _uris; } Engine& engine() { return _engine; } diff --git a/src/server/CompiledGraph.cpp b/src/server/CompiledGraph.cpp index fdf59cd4..b808cb90 100644 --- a/src/server/CompiledGraph.cpp +++ b/src/server/CompiledGraph.cpp @@ -48,13 +48,13 @@ CompiledGraph::CompiledGraph(GraphImpl* graph) compile_graph(graph); } -CompiledGraph* -CompiledGraph::compile(GraphImpl* graph) +MPtr +CompiledGraph::compile(Raul::Maid& maid, GraphImpl& graph) { try { - return new CompiledGraph(graph); + return maid.make_managed(&graph); } catch (FeedbackException e) { - Log& log = graph->engine().log(); + Log& log = graph.engine().log(); if (e.node && e.root) { log.error(fmt("Feedback compiling %1% from %2%\n") % e.node->path() % e.root->path()); @@ -62,7 +62,7 @@ CompiledGraph::compile(GraphImpl* graph) log.error(fmt("Feedback compiling %1%\n") % e.node->path()); } - return NULL; + return MPtr(); } } diff --git a/src/server/CompiledGraph.hpp b/src/server/CompiledGraph.hpp index 7dc40865..eeeb6111 100644 --- a/src/server/CompiledGraph.hpp +++ b/src/server/CompiledGraph.hpp @@ -47,13 +47,15 @@ class CompiledGraph : public Raul::Maid::Disposable , public Raul::Noncopyable { public: - static CompiledGraph* compile(GraphImpl* graph); + static MPtr compile(Raul::Maid& maid, GraphImpl& graph); void run(RunContext& context); void dump(std::function sink) const; private: + friend class Raul::Maid; ///< Allow make_managed to construct + CompiledGraph(GraphImpl* graph); typedef std::set BlockSet; diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp index 41312e65..0fa11a72 100644 --- a/src/server/DuplexPort.cpp +++ b/src/server/DuplexPort.cpp @@ -132,7 +132,7 @@ DuplexPort::on_property(const Raul::URI& uri, const Atom& value) bool DuplexPort::get_buffers(BufferFactory& bufs, PortImpl::GetFn get, - Raul::Array* voices, + const MPtr& voices, uint32_t poly, size_t num_in_arcs) const { @@ -187,14 +187,14 @@ DuplexPort::prepare_poly(BufferFactory& bufs, uint32_t poly) } bool -DuplexPort::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) +DuplexPort::apply_poly(RunContext& context, uint32_t poly) { if (!parent()->parent() || poly != parent()->parent_graph()->internal_poly()) { return false; } - return PortImpl::apply_poly(context, maid, poly); + return PortImpl::apply_poly(context, poly); } void diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp index 8d0443a6..47c24b9e 100644 --- a/src/server/DuplexPort.hpp +++ b/src/server/DuplexPort.hpp @@ -67,11 +67,11 @@ public: bool prepare_poly(BufferFactory& bufs, uint32_t poly); - bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly); + bool apply_poly(RunContext& context, uint32_t poly); bool get_buffers(BufferFactory& bufs, PortImpl::GetFn get, - Raul::Array* voices, + const MPtr& voices, uint32_t poly, size_t num_in_arcs) const; diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp index 6b0c909c..d12f474c 100644 --- a/src/server/Engine.cpp +++ b/src/server/Engine.cpp @@ -67,6 +67,7 @@ bool ThreadManager::single_threaded(true); Engine::Engine(Ingen::World* world) : _world(world) + , _maid(new Raul::Maid) , _block_factory(new BlockFactory(world)) , _broadcaster(new Broadcaster()) , _buffer_factory(new BufferFactory(*this, world->uris())) @@ -74,7 +75,6 @@ Engine::Engine(Ingen::World* world) , _event_writer(new EventWriter(*this)) , _interface(_event_writer) , _atom_interface(nullptr) - , _maid(new Raul::Maid()) , _options(new LV2Options(world->uris())) , _undo_stack(new UndoStack(_world->uris(), _world->uri_map())) , _redo_stack(new UndoStack(_world->uris(), _world->uri_map())) diff --git a/src/server/Engine.hpp b/src/server/Engine.hpp index a4b85562..6e8e74c9 100644 --- a/src/server/Engine.hpp +++ b/src/server/Engine.hpp @@ -186,6 +186,7 @@ private: bool changed = false; }; + Raul::Maid* _maid; BlockFactory* _block_factory; Broadcaster* _broadcaster; BufferFactory* _buffer_factory; @@ -194,7 +195,6 @@ private: SPtr _event_writer; SPtr _interface; AtomReader* _atom_interface; - Raul::Maid* _maid; SPtr _options; UndoStack* _undo_stack; UndoStack* _redo_stack; diff --git a/src/server/GraphImpl.cpp b/src/server/GraphImpl.cpp index dd7be036..6b1d0464 100644 --- a/src/server/GraphImpl.cpp +++ b/src/server/GraphImpl.cpp @@ -52,7 +52,6 @@ GraphImpl::GraphImpl(Engine& engine, , _engine(engine) , _poly_pre(internal_poly) , _poly_process(internal_poly) - , _compiled_graph(NULL) , _process(false) { assert(internal_poly >= 1); @@ -61,7 +60,6 @@ GraphImpl::GraphImpl(Engine& engine, GraphImpl::~GraphImpl() { - delete _compiled_graph; delete _plugin; } @@ -87,14 +85,14 @@ GraphImpl::duplicate(Engine& engine, PortMap port_map; // Add duplicates of all ports - dup->_ports = new Raul::Array(num_ports(), NULL); - for (Ports::iterator p = _inputs.begin(); p != _inputs.end(); ++p) { + dup->_ports = bufs.maid().make_managed(num_ports(), nullptr); + for (PortList::iterator p = _inputs.begin(); p != _inputs.end(); ++p) { DuplexPort* p_dup = p->duplicate(engine, p->symbol(), dup); dup->_inputs.push_front(*p_dup); (*dup->_ports)[p->index()] = p_dup; port_map.insert({&*p, p_dup}); } - for (Ports::iterator p = _outputs.begin(); p != _outputs.end(); ++p) { + for (PortList::iterator p = _outputs.begin(); p != _outputs.end(); ++p) { DuplexPort* p_dup = p->duplicate(engine, p->symbol(), dup); dup->_outputs.push_front(*p_dup); (*dup->_ports)[p->index()] = p_dup; @@ -185,7 +183,7 @@ GraphImpl::apply_internal_poly(RunContext& context, // TODO: Subgraph dynamic polyphony (i.e. changing port polyphony) for (auto& b : _blocks) { - b.apply_poly(context, maid, poly); + b.apply_poly(context, poly); } for (auto& b : _blocks) { @@ -299,15 +297,13 @@ GraphImpl::has_arc(const PortImpl* tail, const PortImpl* dst_port) const return (i != _arcs.end()); } -CompiledGraph* -GraphImpl::swap_compiled_graph(CompiledGraph* cg) +void +GraphImpl::set_compiled_graph(MPtr&& cg) { - CompiledGraph* const old = _compiled_graph; - if (old && cg != old) { + if (_compiled_graph && _compiled_graph != cg) { _engine.reset_load(); } - _compiled_graph = cg; - return old; + _compiled_graph = std::move(cg); } uint32_t @@ -334,20 +330,20 @@ GraphImpl::clear_ports() _outputs.clear(); } -Raul::Array* -GraphImpl::build_ports_array() +MPtr +GraphImpl::build_ports_array(Raul::Maid& maid) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); const size_t n = _inputs.size() + _outputs.size(); - Raul::Array* const result = new Raul::Array(n); + MPtr result = maid.make_managed(n); size_t i = 0; - for (Ports::iterator p = _inputs.begin(); p != _inputs.end(); ++p, ++i) + for (PortList::iterator p = _inputs.begin(); p != _inputs.end(); ++p, ++i) result->at(i) = &*p; - for (Ports::iterator p = _outputs.begin(); p != _outputs.end(); ++p, ++i) + for (PortList::iterator p = _outputs.begin(); p != _outputs.end(); ++p, ++i) result->at(i) = &*p; assert(i == n); diff --git a/src/server/GraphImpl.hpp b/src/server/GraphImpl.hpp index 57e60792..62af07f6 100644 --- a/src/server/GraphImpl.hpp +++ b/src/server/GraphImpl.hpp @@ -119,7 +119,7 @@ public: uint32_t num_ports_non_rt() const; typedef boost::intrusive::slist< - DuplexPort, boost::intrusive::constant_time_size > Ports; + DuplexPort, boost::intrusive::constant_time_size > PortList; void add_input(DuplexPort& port) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); @@ -165,12 +165,13 @@ public: bool has_arc(const PortImpl* tail, const PortImpl* head) const; /** Set a new compiled graph to run, and return the old one. */ - CompiledGraph* swap_compiled_graph(CompiledGraph* cp) INGEN_WARN_UNUSED_RESULT; + void set_compiled_graph(MPtr&& cg); - Raul::Array* external_ports() { return _ports; } - void external_ports(Raul::Array* pa) { _ports = pa; } + const MPtr& external_ports() { return _ports; } - Raul::Array* build_ports_array(); + void set_external_ports(MPtr&& pa) { _ports = std::move(pa); } + + MPtr build_ports_array(Raul::Maid& maid); /** Whether to run this graph's DSP bits in the audio thread */ bool enabled() const { return _process; } @@ -183,14 +184,14 @@ public: Engine& engine() { return _engine; } private: - Engine& _engine; - uint32_t _poly_pre; ///< Pre-process thread only - uint32_t _poly_process; ///< Process thread only - CompiledGraph* _compiled_graph; ///< Process thread only - Ports _inputs; ///< Pre-process thread only - Ports _outputs; ///< Pre-process thread only - Blocks _blocks; ///< Pre-process thread only - bool _process; ///< True iff graph is enabled + Engine& _engine; + uint32_t _poly_pre; ///< Pre-process thread only + uint32_t _poly_process; ///< Process thread only + MPtr _compiled_graph; ///< Process thread only + PortList _inputs; ///< Pre-process thread only + PortList _outputs; ///< Pre-process thread only + Blocks _blocks; ///< Pre-process thread only + bool _process; ///< True iff graph is enabled }; } // namespace Server diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp index 1b4c4501..b0e2ee61 100644 --- a/src/server/InputPort.cpp +++ b/src/server/InputPort.cpp @@ -55,9 +55,9 @@ InputPort::InputPort(BufferFactory& bufs, } bool -InputPort::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) +InputPort::apply_poly(RunContext& context, uint32_t poly) { - bool ret = PortImpl::apply_poly(context, maid, poly); + bool ret = PortImpl::apply_poly(context, poly); if (!ret) poly = 1; @@ -69,7 +69,7 @@ InputPort::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) bool InputPort::get_buffers(BufferFactory& bufs, PortImpl::GetFn get, - Raul::Array* voices, + const MPtr& voices, uint32_t poly, size_t num_in_arcs) const { @@ -99,9 +99,9 @@ InputPort::get_buffers(BufferFactory& bufs, } bool -InputPort::pre_get_buffers(BufferFactory& bufs, - Raul::Array* voices, - uint32_t poly) const +InputPort::pre_get_buffers(BufferFactory& bufs, + MPtr& voices, + uint32_t poly) const { return get_buffers(bufs, &BufferFactory::get_buffer, voices, poly, _num_arcs); } diff --git a/src/server/InputPort.hpp b/src/server/InputPort.hpp index 1fa0293d..73911789 100644 --- a/src/server/InputPort.hpp +++ b/src/server/InputPort.hpp @@ -67,7 +67,7 @@ public: /** Return the maximum polyphony of an output connected to this input. */ virtual uint32_t max_tail_poly(RunContext& context) const; - bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly); + bool apply_poly(RunContext& context, uint32_t poly); /** Add an arc. Realtime safe. * @@ -91,9 +91,9 @@ public: * pre-process thread to allocate buffers for application of a * connection/disconnection/etc in the next process cycle. */ - bool pre_get_buffers(BufferFactory& bufs, - Raul::Array* voices, - uint32_t poly) const; + bool pre_get_buffers(BufferFactory& bufs, + MPtr& voices, + uint32_t poly) const; bool setup_buffers(RunContext& ctx, BufferFactory& bufs, uint32_t poly); @@ -118,7 +118,7 @@ public: protected: bool get_buffers(BufferFactory& bufs, PortImpl::GetFn get, - Raul::Array* voices, + const MPtr& voices, uint32_t poly, size_t num_in_arcs) const; diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp index be02f3ed..ab2582d1 100644 --- a/src/server/LV2Block.cpp +++ b/src/server/LV2Block.cpp @@ -64,8 +64,6 @@ LV2Block::LV2Block(LV2Plugin* plugin, SampleRate srate) : BlockImpl(plugin, symbol, polyphonic, parent, srate) , _lv2_plugin(plugin) - , _instances(NULL) - , _prepared_instances(NULL) , _worker_iface(NULL) { assert(_lv2_plugin); @@ -73,10 +71,12 @@ LV2Block::LV2Block(LV2Plugin* plugin, LV2Block::~LV2Block() { - delete _instances; + // Explicitly drop instances first to prevent reference cycles + drop_instances(_instances); + drop_instances(_prepared_instances); } -SPtr +SPtr LV2Block::make_instance(URIs& uris, SampleRate rate, uint32_t voice, @@ -90,7 +90,7 @@ LV2Block::make_instance(URIs& uris, parent_graph()->engine().log().error( fmt("Failed to instantiate <%1%>\n") % _lv2_plugin->uri().c_str()); - return SPtr(); + return SPtr(); } const LV2_Options_Interface* options_iface = NULL; @@ -145,7 +145,7 @@ LV2Block::make_instance(URIs& uris, parent_graph()->engine().log().error( fmt("%1% auto-morphed to unknown type %2%\n") % port->path().c_str() % type); - return SPtr(); + return SPtr(); } } else { parent_graph()->engine().log().error( @@ -156,7 +156,7 @@ LV2Block::make_instance(URIs& uris, } } - return SPtr(inst, lilv_instance_free); + return std::make_shared(inst); } bool @@ -172,19 +172,19 @@ LV2Block::prepare_poly(BufferFactory& bufs, uint32_t poly) const SampleRate rate = bufs.engine().driver()->sample_rate(); assert(!_prepared_instances); - _prepared_instances = new Instances(poly, *_instances, SPtr()); + _prepared_instances = bufs.maid().make_managed( + poly, *_instances, SPtr()); for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - SPtr inst = make_instance(bufs.uris(), rate, i, true); + SPtr inst = make_instance(bufs.uris(), rate, i, true); if (!inst) { - delete _prepared_instances; - _prepared_instances = NULL; + _prepared_instances.reset(); return false; } _prepared_instances->at(i) = inst; if (_activated) { - lilv_instance_activate(inst.get()); + lilv_instance_activate(inst->instance); } } @@ -192,19 +192,17 @@ LV2Block::prepare_poly(BufferFactory& bufs, uint32_t poly) } bool -LV2Block::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) +LV2Block::apply_poly(RunContext& context, uint32_t poly) { if (!_polyphonic) poly = 1; if (_prepared_instances) { - maid.dispose(_instances); - _instances = _prepared_instances; - _prepared_instances = NULL; + _instances = std::move(_prepared_instances); } assert(poly <= _instances->size()); - return BlockImpl::apply_poly(context, maid, poly); + return BlockImpl::apply_poly(context, poly); } /** Instantiate self from LV2 plugin descriptor. @@ -227,7 +225,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) LilvNode* lv2_connectionOptional = lilv_new_uri( bufs.engine().world()->lilv_world(), LV2_CORE__connectionOptional); - _ports = new Raul::Array(num_ports, NULL); + _ports = bufs.maid().make_managed(num_ports, nullptr); bool ret = true; @@ -416,8 +414,7 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) lilv_node_free(lv2_connectionOptional); if (!ret) { - delete _ports; - _ports = NULL; + _ports.reset(); return ret; } @@ -425,7 +422,8 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) // Actually create plugin instances and port buffers. const SampleRate rate = bufs.engine().driver()->sample_rate(); - _instances = new Instances(_polyphony, SPtr()); + _instances = bufs.maid().make_managed( + _polyphony, SPtr()); for (uint32_t i = 0; i < _polyphony; ++i) { _instances->at(i) = make_instance(bufs.uris(), rate, i, false); if (!_instances->at(i)) { diff --git a/src/server/LV2Block.hpp b/src/server/LV2Block.hpp index b6be8ccf..2ccde602 100644 --- a/src/server/LV2Block.hpp +++ b/src/server/LV2Block.hpp @@ -58,7 +58,7 @@ public: GraphImpl* parent); bool prepare_poly(BufferFactory& bufs, uint32_t poly); - bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly); + bool apply_poly(RunContext& context, uint32_t poly); void activate(BufferFactory& bufs); void deactivate(); @@ -83,16 +83,32 @@ public: static LilvState* load_state(World* world, const std::string& path); protected: - SPtr make_instance(URIs& uris, - SampleRate rate, - uint32_t voice, - bool preparing); + struct Instance : public Raul::Noncopyable { + explicit Instance(LilvInstance* i) : instance(i) {} + + ~Instance() { lilv_instance_free(instance); } + + LilvInstance* const instance; + }; + + SPtr make_instance(URIs& uris, + SampleRate rate, + uint32_t voice, + bool preparing); inline LilvInstance* instance(uint32_t voice) { - return (LilvInstance*)(*_instances)[voice].get(); + return (LilvInstance*)(*_instances)[voice]->instance; } - typedef Raul::Array< SPtr > Instances; + typedef Raul::Array< SPtr > Instances; + + void drop_instances(const MPtr& instances) { + if (instances) { + for (size_t i = 0; i < instances->size(); ++i) { + (*instances)[i].reset(); + } + } + } struct Response : public Raul::Maid::Disposable , public Raul::Noncopyable @@ -122,8 +138,8 @@ protected: LV2_Worker_Respond_Handle handle, uint32_t size, const void* data); LV2Plugin* _lv2_plugin; - Instances* _instances; - Instances* _prepared_instances; + MPtr _instances; + MPtr _prepared_instances; const LV2_Worker_Interface* _worker_iface; std::mutex _work_mutex; Responses _responses; diff --git a/src/server/NodeImpl.hpp b/src/server/NodeImpl.hpp index 517fbdb6..26ef5925 100644 --- a/src/server/NodeImpl.hpp +++ b/src/server/NodeImpl.hpp @@ -84,10 +84,8 @@ public: * * \param context Process context (process thread only). * \param poly Must be <= the most recent value passed to prepare_poly. - * \param maid Any objects no longer needed will be pushed to this */ - virtual bool apply_poly( - RunContext& context, Raul::Maid& maid, uint32_t poly) = 0; + virtual bool apply_poly(RunContext& context, uint32_t poly) = 0; /** Return true iff this is main (the top level Node). * diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index 245173a7..19f71953 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -66,8 +66,7 @@ PortImpl::PortImpl(BufferFactory& bufs, , _value(value) , _min(bufs.forge().make(0.0f)) , _max(bufs.forge().make(1.0f)) - , _voices(new Raul::Array(static_cast(poly))) - , _prepared_voices(NULL) + , _voices(bufs.maid().make_managed(poly)) , _connected_flag(false) , _monitored(false) , _force_monitor_update(false) @@ -106,13 +105,12 @@ PortImpl::PortImpl(BufferFactory& bufs, PortImpl::~PortImpl() { - delete _voices; } bool PortImpl::get_buffers(BufferFactory& bufs, GetFn get, - Raul::Array* voices, + const MPtr& voices, uint32_t poly, size_t num_in_arcs) const { @@ -208,18 +206,11 @@ PortImpl::deactivate() _peak = 0.0f; } -Raul::Array* -PortImpl::set_voices(RunContext& context, Raul::Array* voices) +void +PortImpl::set_voices(RunContext& context, MPtr&& voices) { - Raul::Array* ret = NULL; - if (voices != _voices) { - ret = _voices; - _voices = voices; - } - + _voices = std::move(voices); connect_buffers(); - - return ret; } void @@ -339,12 +330,12 @@ PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) } else if (_poly == poly) { return true; } else if (_prepared_voices && _prepared_voices->size() != poly) { - delete _prepared_voices; - _prepared_voices = NULL; + _prepared_voices.reset(); } if (!_prepared_voices) { - _prepared_voices = new Raul::Array(poly, *_voices, Voice()); + _prepared_voices = bufs.maid().make_managed( + poly, *_voices, Voice()); } get_buffers(bufs, &BufferFactory::get_buffer, @@ -354,7 +345,7 @@ PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly) } bool -PortImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) +PortImpl::apply_poly(RunContext& context, uint32_t poly) { if (_parent->is_main() || (_type == PortType::ATOM && !_value.is_valid())) { @@ -368,9 +359,7 @@ PortImpl::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) _poly = poly; // Apply a new set of voices from a preceding call to prepare_poly - maid.dispose(set_voices(context, _prepared_voices)); - assert(_voices == _prepared_voices); - _prepared_voices = NULL; + _voices = std::move(_prepared_voices); if (is_a(PortType::CONTROL) || is_a(PortType::CV)) { set_control_value(context, context.start(), _value.get()); diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp index fd35b52d..e195de9d 100644 --- a/src/server/PortImpl.hpp +++ b/src/server/PortImpl.hpp @@ -25,7 +25,6 @@ #include "BufferRef.hpp" #include "NodeImpl.hpp" #include "PortType.hpp" -#include "RunContext.hpp" #include "types.hpp" namespace Raul { class Maid; } @@ -35,6 +34,7 @@ namespace Server { class BlockImpl; class BufferFactory; +class RunContext; /** A port (input or output) on a Block. * @@ -84,6 +84,8 @@ public: BufferRef buffer; }; + typedef Raul::Array Voices; + PortImpl(BufferFactory& bufs, BlockImpl* block, const Raul::Symbol& name, @@ -102,13 +104,8 @@ public: /** A port's parent is always a block, so static cast should be safe */ BlockImpl* parent_block() const { return (BlockImpl*)_parent; } - /** Set the buffers array for this port. - * - * Audio thread. Returned value must be freed by caller. - * \a buffers must be poly() long - */ - Raul::Array* set_voices(RunContext& context, - Raul::Array* voices); + /** Set the the voices (buffers) for this port in the audio thread. */ + void set_voices(RunContext& context, MPtr&& voices); /** Prepare for a new (external) polyphony value. * @@ -121,8 +118,7 @@ public: * Audio thread. * \a poly Must be < the most recent value passed to prepare_poly. */ - virtual bool apply_poly( - RunContext& context, Raul::Maid& maid, uint32_t poly); + virtual bool apply_poly(RunContext& context, uint32_t poly); /** Return the number of arcs (pre-process thraed). */ virtual size_t num_arcs() const { return 0; } @@ -280,35 +276,35 @@ protected: */ virtual bool get_buffers(BufferFactory& bufs, GetFn get, - Raul::Array* voices, + const MPtr& voices, uint32_t poly, size_t num_in_arcs) const; - BufferFactory& _bufs; - uint32_t _index; - uint32_t _poly; - uint32_t _buffer_size; - uint32_t _frames_since_monitor; - float _monitor_value; - float _peak; - PortType _type; - LV2_URID _buffer_type; - Atom _value; - Atom _min; - Atom _max; - Raul::Array* _voices; - Raul::Array* _prepared_voices; - BufferRef _user_buffer; - std::atomic_flag _connected_flag; - bool _monitored; - bool _force_monitor_update; - bool _is_morph; - bool _is_auto_morph; - bool _is_logarithmic; - bool _is_sample_rate; - bool _is_toggled; - bool _is_driver_port; - bool _is_output; + BufferFactory& _bufs; + uint32_t _index; + uint32_t _poly; + uint32_t _buffer_size; + uint32_t _frames_since_monitor; + float _monitor_value; + float _peak; + PortType _type; + LV2_URID _buffer_type; + Atom _value; + Atom _min; + Atom _max; + MPtr _voices; + MPtr _prepared_voices; + BufferRef _user_buffer; + std::atomic_flag _connected_flag; + bool _monitored; + bool _force_monitor_update; + bool _is_morph; + bool _is_auto_morph; + bool _is_logarithmic; + bool _is_sample_rate; + bool _is_toggled; + bool _is_driver_port; + bool _is_output; }; } // namespace Server diff --git a/src/server/PreProcessContext.hpp b/src/server/PreProcessContext.hpp index bf1115e8..ee9bed86 100644 --- a/src/server/PreProcessContext.hpp +++ b/src/server/PreProcessContext.hpp @@ -21,6 +21,8 @@ #include "GraphImpl.hpp" +namespace Raul { class Maid; } + namespace Ingen { namespace Server { @@ -44,17 +46,29 @@ public: * This may return false when an atomic bundle is deferring compilation, in * which case the graph is flagged as dirty for later compilation. */ - bool must_compile(GraphImpl* graph) { - if (!graph->enabled()) { + bool must_compile(GraphImpl& graph) { + if (!graph.enabled()) { return false; } else if (_in_bundle) { - _dirty_graphs.insert(graph); + _dirty_graphs.insert(&graph); return false; } else { return true; } } + /** Compile graph and return the result if necessary. + * + * This may return null when an atomic bundle is deferring compilation, in + * which case the graph is flagged as dirty for later compilation. + */ + MPtr maybe_compile(Raul::Maid& maid, GraphImpl& graph) { + if (must_compile(graph)) { + return CompiledGraph::compile(maid, graph); + } + return MPtr(); + } + /** Return all graphs that require compilation after an atomic bundle. */ const DirtyGraphs& dirty_graphs() const { return _dirty_graphs; } DirtyGraphs& dirty_graphs() { return _dirty_graphs; } diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp index eb758940..e933a490 100644 --- a/src/server/events/Connect.cpp +++ b/src/server/events/Connect.cpp @@ -20,6 +20,7 @@ #include "ArcImpl.hpp" #include "Broadcaster.hpp" +#include "BufferFactory.hpp" #include "Connect.hpp" #include "Engine.hpp" #include "GraphImpl.hpp" @@ -44,8 +45,6 @@ Connect::Connect(Engine& engine, , _head_path(head_path) , _graph(NULL) , _head(NULL) - , _compiled_graph(NULL) - , _voices(NULL) {} bool @@ -125,8 +124,9 @@ Connect::pre_process(PreProcessContext& ctx) tail_block->dependants().insert(head_block); } - if (ctx.must_compile(_graph)) { - if (!(_compiled_graph = CompiledGraph::compile(_graph))) { + if (ctx.must_compile(*_graph)) { + if (!(_compiled_graph = CompiledGraph::compile( + *_engine.maid(), *_graph))) { head_block->providers().erase(tail_block); tail_block->dependants().erase(head_block); return Event::pre_process_done(Status::COMPILATION_FAILED); @@ -138,10 +138,9 @@ Connect::pre_process(PreProcessContext& ctx) _head->increment_num_arcs(); if (!_head->is_driver_port()) { - _voices = new Raul::Array(_head->poly()); - _head->pre_get_buffers(*_engine.buffer_factory(), - _voices, - _head->poly()); + BufferFactory& bufs = *_engine.buffer_factory(); + _voices = bufs.maid().make_managed(_head->poly()); + _head->pre_get_buffers(bufs, _voices, _head->poly()); } tail_output->inherit_neighbour(_head, _tail_remove, _tail_add); @@ -156,11 +155,11 @@ Connect::execute(RunContext& context) if (_status == Status::SUCCESS) { _head->add_arc(context, _arc.get()); if (!_head->is_driver_port()) { - _engine.maid()->dispose(_head->set_voices(context, _voices)); + _head->set_voices(context, std::move(_voices)); } _head->connect_buffers(); if (_compiled_graph) { - _compiled_graph = _graph->swap_compiled_graph(_compiled_graph); + _graph->set_compiled_graph(std::move(_compiled_graph)); } } } @@ -180,8 +179,6 @@ Connect::post_process() Node::path_to_uri(_tail_path), _tail_remove, _tail_add); } } - - delete _compiled_graph; } void diff --git a/src/server/events/Connect.hpp b/src/server/events/Connect.hpp index 359c9f3b..8e7a5030 100644 --- a/src/server/events/Connect.hpp +++ b/src/server/events/Connect.hpp @@ -57,17 +57,17 @@ public: void undo(Interface& target); private: - const Raul::Path _tail_path; - const Raul::Path _head_path; - GraphImpl* _graph; - InputPort* _head; - CompiledGraph* _compiled_graph; - SPtr _arc; - Raul::Array* _voices; - Resource::Properties _tail_remove; - Resource::Properties _tail_add; - Resource::Properties _head_remove; - Resource::Properties _head_add; + const Raul::Path _tail_path; + const Raul::Path _head_path; + GraphImpl* _graph; + InputPort* _head; + MPtr _compiled_graph; + SPtr _arc; + MPtr _voices; + Resource::Properties _tail_remove; + Resource::Properties _tail_add; + Resource::Properties _head_remove; + Resource::Properties _head_add; }; } // namespace Events diff --git a/src/server/events/Copy.cpp b/src/server/events/Copy.cpp index 4356e312..58c9a89c 100644 --- a/src/server/events/Copy.cpp +++ b/src/server/events/Copy.cpp @@ -45,7 +45,6 @@ Copy::Copy(Engine& engine, , _old_block(NULL) , _parent(NULL) , _block(NULL) - , _compiled_graph(NULL) {} bool @@ -126,9 +125,7 @@ Copy::engine_to_engine(PreProcessContext& ctx) _engine.store()->add(_block); // Compile graph with new block added for insertion in audio thread - if (ctx.must_compile(_parent)) { - _compiled_graph = CompiledGraph::compile(_parent); - } + _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_parent); return Event::pre_process_done(Status::SUCCESS); } @@ -198,7 +195,7 @@ void Copy::execute(RunContext& context) { if (_block && _compiled_graph) { - _compiled_graph = _parent->swap_compiled_graph(_compiled_graph); + _parent->set_compiled_graph(std::move(_compiled_graph)); } } @@ -209,7 +206,6 @@ Copy::post_process() if (respond() == Status::SUCCESS) { _engine.broadcaster()->copy(_old_uri, _new_uri); } - delete _compiled_graph; } void diff --git a/src/server/events/Copy.hpp b/src/server/events/Copy.hpp index 55310757..e95d905e 100644 --- a/src/server/events/Copy.hpp +++ b/src/server/events/Copy.hpp @@ -56,12 +56,12 @@ private: bool engine_to_filesystem(PreProcessContext& ctx); bool filesystem_to_engine(PreProcessContext& ctx); - const Raul::URI _old_uri; - const Raul::URI _new_uri; - SPtr _old_block; - GraphImpl* _parent; - BlockImpl* _block; - CompiledGraph* _compiled_graph; + const Raul::URI _old_uri; + const Raul::URI _new_uri; + SPtr _old_block; + GraphImpl* _parent; + BlockImpl* _block; + MPtr _compiled_graph; }; } // namespace Events diff --git a/src/server/events/CreateBlock.cpp b/src/server/events/CreateBlock.cpp index a43a8bf0..255746b1 100644 --- a/src/server/events/CreateBlock.cpp +++ b/src/server/events/CreateBlock.cpp @@ -46,12 +46,10 @@ CreateBlock::CreateBlock(Engine& engine, , _properties(properties) , _graph(NULL) , _block(NULL) - , _compiled_graph(NULL) {} CreateBlock::~CreateBlock() { - delete _compiled_graph; } bool @@ -150,9 +148,7 @@ CreateBlock::pre_process(PreProcessContext& ctx) /* Compile graph with new block added for insertion in audio thread TODO: Since the block is not connected at this point, a full compilation could be avoided and the block simply appended. */ - if (ctx.must_compile(_graph)) { - _compiled_graph = CompiledGraph::compile(_graph); - } + _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_graph); _update.put_block(_block); @@ -163,7 +159,7 @@ void CreateBlock::execute(RunContext& context) { if (_status == Status::SUCCESS && _compiled_graph) { - _compiled_graph = _graph->swap_compiled_graph(_compiled_graph); + _graph->set_compiled_graph(std::move(_compiled_graph)); } } diff --git a/src/server/events/CreateBlock.hpp b/src/server/events/CreateBlock.hpp index b0aa6aa4..047c01f3 100644 --- a/src/server/events/CreateBlock.hpp +++ b/src/server/events/CreateBlock.hpp @@ -58,7 +58,7 @@ private: ClientUpdate _update; GraphImpl* _graph; BlockImpl* _block; - CompiledGraph* _compiled_graph; + MPtr _compiled_graph; }; } // namespace Events diff --git a/src/server/events/CreateGraph.cpp b/src/server/events/CreateGraph.cpp index a59aadc6..7ebaeedc 100644 --- a/src/server/events/CreateGraph.cpp +++ b/src/server/events/CreateGraph.cpp @@ -42,7 +42,6 @@ CreateGraph::CreateGraph(Engine& engine, , _properties(properties) , _graph(NULL) , _parent(NULL) - , _compiled_graph(NULL) {} CreateGraph::~CreateGraph() @@ -50,8 +49,6 @@ CreateGraph::~CreateGraph() for (Event* ev : _child_events) { delete ev; } - - delete _compiled_graph; } void @@ -173,9 +170,7 @@ CreateGraph::pre_process(PreProcessContext& ctx) if (_parent->enabled()) { _graph->enable(); } - if (ctx.must_compile(_parent)) { - _compiled_graph = CompiledGraph::compile(_parent); - } + _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_parent); } _graph->activate(*_engine.buffer_factory()); @@ -201,7 +196,7 @@ CreateGraph::execute(RunContext& context) { if (_graph) { if (_parent && _compiled_graph) { - _compiled_graph = _parent->swap_compiled_graph(_compiled_graph); + _parent->set_compiled_graph(std::move(_compiled_graph)); } for (Event* ev : _child_events) { diff --git a/src/server/events/CreateGraph.hpp b/src/server/events/CreateGraph.hpp index 7eee9c08..896a18f9 100644 --- a/src/server/events/CreateGraph.hpp +++ b/src/server/events/CreateGraph.hpp @@ -56,13 +56,13 @@ public: private: void build_child_events(); - const Raul::Path _path; - Resource::Properties _properties; - ClientUpdate _update; - GraphImpl* _graph; - GraphImpl* _parent; - CompiledGraph* _compiled_graph; - std::list _child_events; + const Raul::Path _path; + Resource::Properties _properties; + ClientUpdate _update; + GraphImpl* _graph; + GraphImpl* _parent; + MPtr _compiled_graph; + std::list _child_events; }; } // namespace Events diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp index bb8bb4d4..b6cabbeb 100644 --- a/src/server/events/CreatePort.cpp +++ b/src/server/events/CreatePort.cpp @@ -48,8 +48,6 @@ CreatePort::CreatePort(Engine& engine, , _buf_type(0) , _graph(NULL) , _graph_port(NULL) - , _ports_array(NULL) - , _old_ports_array(NULL) , _engine_port(NULL) , _properties(properties) { @@ -156,8 +154,10 @@ CreatePort::pre_process(PreProcessContext& ctx) _engine_port = _engine.driver()->create_port(_graph_port); } - _ports_array = new Raul::Array(old_n_ports + 1, NULL); - _update = _graph_port->properties(); + _ports_array = bufs.maid().make_managed( + old_n_ports + 1, nullptr); + + _update = _graph_port->properties(); assert(_graph_port->index() == (uint32_t)index_i->second.get()); assert(_graph->num_ports_non_rt() == (uint32_t)old_n_ports + 1); @@ -171,15 +171,15 @@ void CreatePort::execute(RunContext& context) { if (_status == Status::SUCCESS) { - _old_ports_array = _graph->external_ports(); - if (_old_ports_array) { - for (uint32_t i = 0; i < _old_ports_array->size(); ++i) { - (*_ports_array)[i] = (*_old_ports_array)[i]; + const MPtr& old_ports = _graph->external_ports(); + if (old_ports) { + for (uint32_t i = 0; i < old_ports->size(); ++i) { + (*_ports_array)[i] = (*old_ports)[i]; } } assert(!(*_ports_array)[_graph_port->index()]); (*_ports_array)[_graph_port->index()] = _graph_port; - _graph->external_ports(_ports_array); + _graph->set_external_ports(std::move(_ports_array)); if (_engine_port) { _engine.driver()->add_port(context, _engine_port); @@ -194,8 +194,6 @@ CreatePort::post_process() if (respond() == Status::SUCCESS) { _engine.broadcaster()->put(Node::path_to_uri(_path), _update); } - - delete _old_ports_array; } void diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp index f3e2092d..2d32f1dd 100644 --- a/src/server/events/CreatePort.hpp +++ b/src/server/events/CreatePort.hpp @@ -24,6 +24,7 @@ #include "raul/Array.hpp" #include "raul/Path.hpp" +#include "BlockImpl.hpp" #include "Event.hpp" #include "PortType.hpp" @@ -67,8 +68,7 @@ private: LV2_URID _buf_type; GraphImpl* _graph; DuplexPort* _graph_port; - Raul::Array* _ports_array; ///< New external port array for Graph - Raul::Array* _old_ports_array; + MPtr _ports_array; ///< New external port array for Graph EnginePort* _engine_port; ///< Driver port if on the root Resource::Properties _properties; Resource::Properties _update; diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp index b77f7c3e..788dfa2b 100644 --- a/src/server/events/Delete.cpp +++ b/src/server/events/Delete.cpp @@ -43,8 +43,6 @@ Delete::Delete(Engine& engine, : Event(engine, client, id, time) , _uri(uri) , _engine_port(NULL) - , _ports_array(NULL) - , _compiled_graph(NULL) , _disconnect_event(NULL) { if (Node::uri_is_path(uri)) { @@ -55,7 +53,6 @@ Delete::Delete(Engine& engine, Delete::~Delete() { delete _disconnect_event; - delete _compiled_graph; for (ControlBindings::Binding* b : _removed_bindings) { delete b; } @@ -97,21 +94,15 @@ Delete::pre_process(PreProcessContext& ctx) parent->remove_block(*_block); _disconnect_event = new DisconnectAll(_engine, parent, _block.get()); _disconnect_event->pre_process(ctx); - - if (ctx.must_compile(parent)) { - _compiled_graph = CompiledGraph::compile(parent); - } + _compiled_graph = ctx.maybe_compile(*_engine.maid(), *parent); } else if (_port) { parent->remove_port(*_port); _disconnect_event = new DisconnectAll(_engine, parent, _port.get()); _disconnect_event->pre_process(ctx); - if (ctx.must_compile(parent)) { - _compiled_graph = CompiledGraph::compile(parent); - } - + _compiled_graph = ctx.maybe_compile(*_engine.maid(), *parent); if (parent->enabled()) { - _ports_array = parent->build_ports_array(); + _ports_array = parent->build_ports_array(*_engine.maid()); assert(_ports_array->size() == parent->num_ports_non_rt()); } @@ -141,8 +132,7 @@ Delete::execute(RunContext& context) GraphImpl* parent = _block ? _block->parent_graph() : NULL; if (_port) { parent = _port->parent_graph(); - _engine.maid()->dispose(parent->external_ports()); - parent->external_ports(_ports_array); + parent->set_external_ports(std::move(_ports_array)); if (_engine_port) { _engine.driver()->remove_port(context, _engine_port); @@ -150,7 +140,7 @@ Delete::execute(RunContext& context) } if (parent && _compiled_graph) { - _compiled_graph = parent->swap_compiled_graph(_compiled_graph); + parent->set_compiled_graph(std::move(_compiled_graph)); } } diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp index 1b34faf6..224cad3b 100644 --- a/src/server/events/Delete.hpp +++ b/src/server/events/Delete.hpp @@ -65,8 +65,8 @@ private: SPtr _block; ///< Non-NULL iff a block SPtr _port; ///< Non-NULL iff a port EnginePort* _engine_port; - Raul::Array* _ports_array; ///< New (external) ports for Graph - CompiledGraph* _compiled_graph; ///< Graph's new process order + MPtr _ports_array; ///< New (external) ports for Graph + MPtr _compiled_graph; ///< Graph's new process order DisconnectAll* _disconnect_event; Store::Objects _removed_objects; diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index 2ad258fd..2c13f9d4 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -60,7 +60,6 @@ Delta::Delta(Engine& engine, , _remove(remove) , _object(NULL) , _graph(NULL) - , _compiled_graph(NULL) , _binding(NULL) , _state(NULL) , _context(context) @@ -87,7 +86,6 @@ Delta::~Delta() delete s; delete _create_event; - delete _compiled_graph; } void @@ -355,7 +353,8 @@ Delta::pre_process(PreProcessContext& ctx) op = SpecialType::ENABLE; // FIXME: defer this until all other metadata has been processed if (value.get() && !_graph->enabled()) { - if (!(_compiled_graph = CompiledGraph::compile(_graph))) { + if (!(_compiled_graph = CompiledGraph::compile( + *_engine.maid(), *_graph))) { _status = Status::COMPILATION_FAILED; } } @@ -476,7 +475,7 @@ Delta::execute(RunContext& context) if (_graph) { if (value.get()) { if (_compiled_graph) { - _compiled_graph = _graph->swap_compiled_graph(_compiled_graph); + _graph->set_compiled_graph(std::move(_compiled_graph)); } _graph->enable(); } else { @@ -489,10 +488,9 @@ Delta::execute(RunContext& context) case SpecialType::POLYPHONIC: { GraphImpl* parent = reinterpret_cast(object->parent()); if (value.get()) { - object->apply_poly( - context, *_engine.maid(), parent->internal_poly_process()); + object->apply_poly(context, parent->internal_poly_process()); } else { - object->apply_poly(context, *_engine.maid(), 1); + object->apply_poly(context, 1); } } break; case SpecialType::POLYPHONY: diff --git a/src/server/events/Delta.hpp b/src/server/events/Delta.hpp index d2326cd9..d751afc7 100644 --- a/src/server/events/Delta.hpp +++ b/src/server/events/Delta.hpp @@ -104,7 +104,7 @@ private: ClientUpdate _update; Ingen::Resource* _object; GraphImpl* _graph; - CompiledGraph* _compiled_graph; + MPtr _compiled_graph; ControlBindings::Binding* _binding; LilvState* _state; Resource::Graph _context; diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp index 3233cac4..9320163a 100644 --- a/src/server/events/Disconnect.cpp +++ b/src/server/events/Disconnect.cpp @@ -48,14 +48,12 @@ Disconnect::Disconnect(Engine& engine, , _head_path(head_path) , _graph(NULL) , _impl(NULL) - , _compiled_graph(NULL) { } Disconnect::~Disconnect() { delete _impl; - delete _compiled_graph; } Disconnect::Impl::Impl(Engine& e, @@ -66,7 +64,6 @@ Disconnect::Impl::Impl(Engine& e, , _tail(t) , _head(h) , _arc(graph->remove_arc(_tail, _head)) - , _voices(NULL) { ThreadManager::assert_thread(THREAD_PRE_PROCESS); @@ -89,10 +86,9 @@ Disconnect::Impl::Impl(Engine& e, if (_head->num_arcs() == 0) { if (!_head->is_driver_port()) { - _voices = new Raul::Array(_head->poly()); - _head->pre_get_buffers(*_engine.buffer_factory(), - _voices, - _head->poly()); + BufferFactory& bufs = *_engine.buffer_factory(); + _voices = bufs.maid().make_managed(_head->poly()); + _head->pre_get_buffers(bufs, _voices, _head->poly()); if (_head->is_a(PortType::CONTROL) || _head->is_a(PortType::CV)) { @@ -166,9 +162,7 @@ Disconnect::pre_process(PreProcessContext& ctx) dynamic_cast(tail), dynamic_cast(head)); - if (ctx.must_compile(_graph)) { - _compiled_graph = CompiledGraph::compile(_graph); - } + _compiled_graph = ctx.maybe_compile(*_engine.maid(), *_graph); return Event::pre_process_done(Status::SUCCESS); } @@ -186,7 +180,7 @@ Disconnect::Impl::execute(RunContext& context, bool set_head_buffers) if (set_head_buffers) { if (_voices) { - _engine.maid()->dispose(_head->set_voices(context, _voices)); + _head->set_voices(context, std::move(_voices)); } else { _head->setup_buffers(context, *_engine.buffer_factory(), _head->poly()); } @@ -204,7 +198,7 @@ Disconnect::execute(RunContext& context) if (_status == Status::SUCCESS) { if (_impl->execute(context, true)) { if (_compiled_graph) { - _compiled_graph = _graph->swap_compiled_graph(_compiled_graph); + _graph->set_compiled_graph(std::move(_compiled_graph)); } } else { _status = Status::NOT_FOUND; diff --git a/src/server/events/Disconnect.hpp b/src/server/events/Disconnect.hpp index fa16f01f..3a7e0cff 100644 --- a/src/server/events/Disconnect.hpp +++ b/src/server/events/Disconnect.hpp @@ -60,10 +60,7 @@ public: class Impl { public: - Impl(Engine& e, - GraphImpl* graph, - PortImpl* t, - InputPort* h); + Impl(Engine& e, GraphImpl* graph, PortImpl* t, InputPort* h); bool execute(RunContext& context, bool set_head_buffers); @@ -71,19 +68,19 @@ public: inline InputPort* head() { return _head; } private: - Engine& _engine; - PortImpl* _tail; - InputPort* _head; - SPtr _arc; - Raul::Array* _voices; + Engine& _engine; + PortImpl* _tail; + InputPort* _head; + SPtr _arc; + MPtr _voices; }; private: - const Raul::Path _tail_path; - const Raul::Path _head_path; - GraphImpl* _graph; - Impl* _impl; - CompiledGraph* _compiled_graph; + const Raul::Path _tail_path; + const Raul::Path _head_path; + GraphImpl* _graph; + Impl* _impl; + MPtr _compiled_graph; }; } // namespace Events diff --git a/src/server/events/DisconnectAll.cpp b/src/server/events/DisconnectAll.cpp index 597f8e9b..16b62302 100644 --- a/src/server/events/DisconnectAll.cpp +++ b/src/server/events/DisconnectAll.cpp @@ -51,7 +51,6 @@ DisconnectAll::DisconnectAll(Engine& engine, , _parent(NULL) , _block(NULL) , _port(NULL) - , _compiled_graph(NULL) , _deleting(false) { } @@ -67,7 +66,6 @@ DisconnectAll::DisconnectAll(Engine& engine, , _parent(parent) , _block(dynamic_cast(object)) , _port(dynamic_cast(object)) - , _compiled_graph(NULL) , _deleting(true) { } @@ -76,8 +74,6 @@ DisconnectAll::~DisconnectAll() { for (auto& i : _impls) delete i; - - delete _compiled_graph; } bool @@ -138,8 +134,9 @@ DisconnectAll::pre_process(PreProcessContext& ctx) dynamic_cast(a->head()))); } - if (!_deleting && ctx.must_compile(_parent)) { - if (!(_compiled_graph = CompiledGraph::compile(_parent))) { + if (!_deleting && ctx.must_compile(*_parent)) { + if (!(_compiled_graph = CompiledGraph::compile( + *_engine.maid(), *_parent))) { return Event::pre_process_done(Status::COMPILATION_FAILED); } } @@ -158,7 +155,7 @@ DisconnectAll::execute(RunContext& context) } if (_compiled_graph) { - _compiled_graph = _parent->swap_compiled_graph(_compiled_graph); + _parent->set_compiled_graph(std::move(_compiled_graph)); } } diff --git a/src/server/events/DisconnectAll.hpp b/src/server/events/DisconnectAll.hpp index 1fc1f757..abfa0572 100644 --- a/src/server/events/DisconnectAll.hpp +++ b/src/server/events/DisconnectAll.hpp @@ -64,14 +64,14 @@ public: private: typedef std::list Impls; - Raul::Path _parent_path; - Raul::Path _path; - GraphImpl* _parent; - BlockImpl* _block; - PortImpl* _port; - Impls _impls; - CompiledGraph* _compiled_graph; - bool _deleting; + Raul::Path _parent_path; + Raul::Path _path; + GraphImpl* _parent; + BlockImpl* _block; + PortImpl* _port; + Impls _impls; + MPtr _compiled_graph; + bool _deleting; }; } // namespace Events diff --git a/src/server/events/Mark.cpp b/src/server/events/Mark.cpp index c72cc14f..eee2d552 100644 --- a/src/server/events/Mark.cpp +++ b/src/server/events/Mark.cpp @@ -35,9 +35,6 @@ Mark::Mark(Engine& engine, Mark::~Mark() { - for (const auto& g : _compiled_graphs) { - delete g.second; - } } bool @@ -57,9 +54,10 @@ Mark::pre_process(PreProcessContext& ctx) ctx.set_in_bundle(false); if (!ctx.dirty_graphs().empty()) { for (GraphImpl* g : ctx.dirty_graphs()) { - CompiledGraph* cg = CompiledGraph::compile(g); + MPtr cg = CompiledGraph::compile( + *_engine.maid(), *g); if (cg) { - _compiled_graphs.insert(std::make_pair(g, cg)); + _compiled_graphs.insert(std::make_pair(g, std::move(cg))); } } ctx.dirty_graphs().clear(); @@ -74,7 +72,7 @@ void Mark::execute(RunContext& context) { for (auto& g : _compiled_graphs) { - g.second = g.first->swap_compiled_graph(g.second); + g.first->set_compiled_graph(std::move(g.second)); } } diff --git a/src/server/events/Mark.hpp b/src/server/events/Mark.hpp index 68ba5149..4a5e83bf 100644 --- a/src/server/events/Mark.hpp +++ b/src/server/events/Mark.hpp @@ -53,7 +53,7 @@ public: Execution get_execution() const; private: - typedef std::map CompiledGraphs; + typedef std::map> CompiledGraphs; CompiledGraphs _compiled_graphs; Type _type; diff --git a/src/server/internals/BlockDelay.cpp b/src/server/internals/BlockDelay.cpp index d52ae721..c0e8dded 100644 --- a/src/server/internals/BlockDelay.cpp +++ b/src/server/internals/BlockDelay.cpp @@ -47,7 +47,7 @@ BlockDelayNode::BlockDelayNode(InternalPlugin* plugin, : InternalBlock(plugin, symbol, polyphonic, parent, srate) { const Ingen::URIs& uris = bufs.uris(); - _ports = new Raul::Array(2); + _ports = bufs.maid().make_managed(2); _in_port = new InputPort(bufs, this, Raul::Symbol("in"), 0, 1, PortType::AUDIO, 0, bufs.forge().make(0.0f)); diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp index 4b6f9c02..0366cbf0 100644 --- a/src/server/internals/Controller.cpp +++ b/src/server/internals/Controller.cpp @@ -51,7 +51,7 @@ ControllerNode::ControllerNode(InternalPlugin* plugin, , _learning(false) { const Ingen::URIs& uris = bufs.uris(); - _ports = new Raul::Array(7); + _ports = bufs.maid().make_managed(7); const Atom zero = bufs.forge().make(0.0f); const Atom one = bufs.forge().make(1.0f); diff --git a/src/server/internals/Note.cpp b/src/server/internals/Note.cpp index 564ae34c..cc592794 100644 --- a/src/server/internals/Note.cpp +++ b/src/server/internals/Note.cpp @@ -53,12 +53,11 @@ NoteNode::NoteNode(InternalPlugin* plugin, GraphImpl* parent, SampleRate srate) : InternalBlock(plugin, symbol, polyphonic, parent, srate) - , _voices(new Raul::Array(_polyphony)) - , _prepared_voices(NULL) + , _voices(bufs.maid().make_managed(_polyphony)) , _sustain(false) { const Ingen::URIs& uris = bufs.uris(); - _ports = new Raul::Array(8); + _ports = bufs.maid().make_managed(8); const Atom zero = bufs.forge().make(0.0f); const Atom one = bufs.forge().make(1.0f); @@ -131,7 +130,6 @@ NoteNode::NoteNode(InternalPlugin* plugin, NoteNode::~NoteNode() { - delete _voices; } bool @@ -145,22 +143,21 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly) if (_prepared_voices && poly <= _prepared_voices->size()) return true; - _prepared_voices = new Raul::Array(poly, *_voices, Voice()); + _prepared_voices = bufs.maid().make_managed( + poly, *_voices, Voice()); return true; } bool -NoteNode::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) +NoteNode::apply_poly(RunContext& context, uint32_t poly) { - if (!BlockImpl::apply_poly(context, maid, poly)) + if (!BlockImpl::apply_poly(context, poly)) return false; if (_prepared_voices) { assert(_polyphony <= _prepared_voices->size()); - maid.dispose(_voices); - _voices = _prepared_voices; - _prepared_voices = NULL; + _voices = std::move(_prepared_voices); } assert(_polyphony <= _voices->size()); diff --git a/src/server/internals/Note.hpp b/src/server/internals/Note.hpp index 08d1b358..e8593768 100644 --- a/src/server/internals/Note.hpp +++ b/src/server/internals/Note.hpp @@ -48,7 +48,7 @@ public: ~NoteNode(); bool prepare_poly(BufferFactory& bufs, uint32_t poly); - bool apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly); + bool apply_poly(RunContext& context, uint32_t poly); void run(RunContext& context); @@ -84,12 +84,15 @@ private: SampleCount time; }; + typedef Raul::Array Voices; + void free_voice(RunContext& context, uint32_t voice, FrameTime time); - Raul::Array* _voices; - Raul::Array* _prepared_voices; - Key _keys[128]; - bool _sustain; ///< Whether or not hold pedal is depressed + MPtr _voices; + MPtr _prepared_voices; + + Key _keys[128]; + bool _sustain; ///< Whether or not hold pedal is depressed InputPort* _midi_in_port; OutputPort* _freq_port; diff --git a/src/server/internals/Time.cpp b/src/server/internals/Time.cpp index 0f4bdd56..2da2a2ae 100644 --- a/src/server/internals/Time.cpp +++ b/src/server/internals/Time.cpp @@ -45,7 +45,7 @@ TimeNode::TimeNode(InternalPlugin* plugin, : InternalBlock(plugin, symbol, false, parent, srate) { const Ingen::URIs& uris = bufs.uris(); - _ports = new Raul::Array(1); + _ports = bufs.maid().make_managed(1); _notify_port = new OutputPort( bufs, this, Raul::Symbol("notify"), 0, 1, diff --git a/src/server/internals/Trigger.cpp b/src/server/internals/Trigger.cpp index 68089283..88bfd3f1 100644 --- a/src/server/internals/Trigger.cpp +++ b/src/server/internals/Trigger.cpp @@ -51,7 +51,7 @@ TriggerNode::TriggerNode(InternalPlugin* plugin, , _learning(false) { const Ingen::URIs& uris = bufs.uris(); - _ports = new Raul::Array(6); + _ports = bufs.maid().make_managed(6); const Atom zero = bufs.forge().make(0.0f); diff --git a/wscript b/wscript index bdd4ef1f..7a15d63f 100644 --- a/wscript +++ b/wscript @@ -85,7 +85,7 @@ def configure(conf): autowaf.check_pkg(conf, 'sratom-0', uselib_store='SRATOM', atleast_version='0.4.6', mandatory=True) autowaf.check_pkg(conf, 'raul', uselib_store='RAUL', - atleast_version='0.8.6', mandatory=True) + atleast_version='0.8.7', mandatory=True) autowaf.check_pkg(conf, 'serd-0', uselib_store='SERD', atleast_version='0.18.0', mandatory=False) autowaf.check_pkg(conf, 'sord-0', uselib_store='SORD', -- cgit v1.2.1