summaryrefslogtreecommitdiffstats
path: root/src/libs/engine/events/AddPortEvent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/engine/events/AddPortEvent.cpp')
-rw-r--r--src/libs/engine/events/AddPortEvent.cpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp
index 06ddae94..ae692b1b 100644
--- a/src/libs/engine/events/AddPortEvent.cpp
+++ b/src/libs/engine/events/AddPortEvent.cpp
@@ -23,6 +23,7 @@
#include "Patch.h"
#include "Maid.h"
#include "util/Path.h"
+#include "QueuedEventSource.h"
#include "ObjectStore.h"
#include "ClientBroadcaster.h"
#include "util/Path.h"
@@ -32,12 +33,13 @@
#include "List.h"
#include "Driver.h"
#include "DuplexPort.h"
+#include "Array.h"
namespace Ingen {
-AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output)
-: QueuedEvent(engine, responder, timestamp),
+AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source)
+: QueuedEvent(engine, responder, timestamp, true, source),
_path(path),
_type(type),
_is_output(is_output),
@@ -46,6 +48,14 @@ AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, Samp
_patch_port(NULL),
_driver_port(NULL)
{
+ /* This is blocking because of the two different sets of Patch ports, the array used in the
+ * audio thread (inherited from NodeBase), and the arrays used in the pre processor thread.
+ * If two add port events arrive in the same cycle and the second pre processes before the
+ * first executes, bad things happen (ports are lost).
+ *
+ * FIXME: fix this using RCU
+ */
+
string type_str;
if (type == "CONTROL" || type == "AUDIO")
_data_type = DataType::FLOAT;
@@ -73,17 +83,22 @@ AddPortEvent::pre_process()
if (_type == "AUDIO" || _type == "MIDI")
buffer_size = _engine.audio_driver()->buffer_size();
+ const size_t old_num_ports = _patch->num_ports();
+
_patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output);
+
if (_patch_port) {
+
if (_is_output)
_patch->add_output(new ListNode<Port*>(_patch_port));
else
_patch->add_input(new ListNode<Port*>(_patch_port));
if (_patch->external_ports())
- _ports_array = new Array<Port*>(_patch->num_ports() + 1, *_patch->external_ports());
+ _ports_array = new Array<Port*>(old_num_ports + 1, *_patch->external_ports());
else
- _ports_array = new Array<Port*>(_patch->num_ports() + 1, NULL);
+ _ports_array = new Array<Port*>(old_num_ports + 1, NULL);
+
_ports_array->at(_patch->num_ports()) = _patch_port;
_engine.object_store()->add(_patch_port);
@@ -96,6 +111,9 @@ AddPortEvent::pre_process()
_driver_port = _engine.midi_driver()->create_port(
dynamic_cast<DuplexPort<MidiMessage>*>(_patch_port));
}
+
+ assert(_patch->num_ports() == old_num_ports);
+ assert(_ports_array->size() == _patch->num_ports() + 1);
}
}
QueuedEvent::pre_process();
@@ -108,8 +126,10 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
QueuedEvent::execute(nframes, start, end);
if (_patch_port) {
+
_engine.maid()->push(_patch->external_ports());
//_patch->add_port(_port);
+
_patch->external_ports(_ports_array);
}
@@ -121,6 +141,9 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
void
AddPortEvent::post_process()
{
+ if (_source)
+ _source->unblock();
+
if (!_patch_port) {
const string msg = string("Could not create port - ").append(_path);
_responder->respond_error(msg);