Fix crash when resetting MIDI tracer
The GUI was able to free memory (MidiTracer::disconnect), while the tracer is concurrently still in use in rt-context. This lead to memory corruption in MIDI::Parser::scanner.
This commit is contained in:
parent
d16c5d69ed
commit
7e567468b2
@ -59,7 +59,7 @@ class LIBARDOUR_API MidiPort : public Port {
|
|||||||
|
|
||||||
MidiBuffer& get_midi_buffer (pframes_t nframes);
|
MidiBuffer& get_midi_buffer (pframes_t nframes);
|
||||||
|
|
||||||
void set_trace (MIDI::Parser* trace_parser);
|
void set_trace (std::weak_ptr<MIDI::Parser> trace_parser);
|
||||||
|
|
||||||
typedef boost::function<bool(MidiBuffer&,MidiBuffer&)> MidiFilter;
|
typedef boost::function<bool(MidiBuffer&,MidiBuffer&)> MidiFilter;
|
||||||
void set_inbound_filter (MidiFilter);
|
void set_inbound_filter (MidiFilter);
|
||||||
@ -80,7 +80,7 @@ private:
|
|||||||
MidiFilter _inbound_midi_filter;
|
MidiFilter _inbound_midi_filter;
|
||||||
std::shared_ptr<MidiPort> _shadow_port;
|
std::shared_ptr<MidiPort> _shadow_port;
|
||||||
MidiFilter _shadow_midi_filter;
|
MidiFilter _shadow_midi_filter;
|
||||||
MIDI::Parser* _trace_parser;
|
std::weak_ptr<MIDI::Parser> _trace_parser;
|
||||||
bool _data_fetched_for_cycle;
|
bool _data_fetched_for_cycle;
|
||||||
|
|
||||||
void resolve_notes (void* buffer, samplepos_t when);
|
void resolve_notes (void* buffer, samplepos_t when);
|
||||||
|
@ -934,7 +934,7 @@ class LIBARDOUR_API TriggerBox : public Processor
|
|||||||
static CustomMidiMap _custom_midi_map;
|
static CustomMidiMap _custom_midi_map;
|
||||||
|
|
||||||
static void midi_input_handler (MIDI::Parser&, MIDI::byte*, size_t, samplecnt_t);
|
static void midi_input_handler (MIDI::Parser&, MIDI::byte*, size_t, samplecnt_t);
|
||||||
static MIDI::Parser* input_parser;
|
static std::shared_ptr<MIDI::Parser> input_parser;
|
||||||
static PBD::ScopedConnection midi_input_connection;
|
static PBD::ScopedConnection midi_input_connection;
|
||||||
static void input_port_check ();
|
static void input_port_check ();
|
||||||
static PBD::ScopedConnectionList static_connections;
|
static PBD::ScopedConnectionList static_connections;
|
||||||
|
@ -43,7 +43,6 @@ MidiPort::MidiPort (const std::string& name, PortFlags flags)
|
|||||||
: Port (name, DataType::MIDI, flags)
|
: Port (name, DataType::MIDI, flags)
|
||||||
, _resolve_required (false)
|
, _resolve_required (false)
|
||||||
, _input_active (true)
|
, _input_active (true)
|
||||||
, _trace_parser (0)
|
|
||||||
, _data_fetched_for_cycle (false)
|
, _data_fetched_for_cycle (false)
|
||||||
{
|
{
|
||||||
_buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI));
|
_buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI));
|
||||||
@ -75,8 +74,11 @@ MidiPort::cycle_start (pframes_t nframes)
|
|||||||
port_engine.midi_clear (port_engine.get_buffer (_port_handle, nframes));
|
port_engine.midi_clear (port_engine.get_buffer (_port_handle, nframes));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (receives_input() && _trace_parser) {
|
if (receives_input()) {
|
||||||
read_and_parse_entire_midi_buffer_with_no_speed_adjustment (nframes, *_trace_parser, AudioEngine::instance()->sample_time_at_cycle_start());
|
std::shared_ptr<MIDI::Parser> trace_parser = _trace_parser.lock ();
|
||||||
|
if (trace_parser) {
|
||||||
|
read_and_parse_entire_midi_buffer_with_no_speed_adjustment (nframes, *trace_parser.get(), AudioEngine::instance()->sample_time_at_cycle_start());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_inbound_midi_filter) {
|
if (_inbound_midi_filter) {
|
||||||
@ -293,16 +295,19 @@ MidiPort::flush_buffers (pframes_t nframes)
|
|||||||
|
|
||||||
const samplepos_t adjusted_time = ev.time() + _global_port_buffer_offset;
|
const samplepos_t adjusted_time = ev.time() + _global_port_buffer_offset;
|
||||||
|
|
||||||
if (sends_output() && _trace_parser) {
|
if (sends_output()) {
|
||||||
uint8_t const * const buf = ev.buffer();
|
std::shared_ptr<MIDI::Parser> trace_parser = _trace_parser.lock ();
|
||||||
const samplepos_t now = AudioEngine::instance()->sample_time_at_cycle_start();
|
if (trace_parser) {
|
||||||
|
uint8_t const * const buf = ev.buffer();
|
||||||
|
const samplepos_t now = AudioEngine::instance()->sample_time_at_cycle_start();
|
||||||
|
|
||||||
_trace_parser->set_timestamp (now + adjusted_time / speed_ratio);
|
trace_parser->set_timestamp (now + adjusted_time / speed_ratio);
|
||||||
|
|
||||||
uint32_t limit = ev.size();
|
uint32_t limit = ev.size();
|
||||||
|
|
||||||
for (size_t n = 0; n < limit; ++n) {
|
for (size_t n = 0; n < limit; ++n) {
|
||||||
_trace_parser->scanner (buf[n]);
|
trace_parser->scanner (buf[n]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +391,7 @@ MidiPort::reset ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiPort::set_trace (MIDI::Parser * p)
|
MidiPort::set_trace (std::weak_ptr<MIDI::Parser> p)
|
||||||
{
|
{
|
||||||
_trace_parser = p;
|
_trace_parser = p;
|
||||||
}
|
}
|
||||||
|
@ -3049,7 +3049,7 @@ TriggerBox::CustomMidiMap TriggerBox::_custom_midi_map;
|
|||||||
std::pair<int,int> TriggerBox::learning_for;
|
std::pair<int,int> TriggerBox::learning_for;
|
||||||
PBD::Signal0<void> TriggerBox::TriggerMIDILearned;
|
PBD::Signal0<void> TriggerBox::TriggerMIDILearned;
|
||||||
|
|
||||||
MIDI::Parser* TriggerBox::input_parser (new MIDI::Parser); /* leak */
|
std::shared_ptr<MIDI::Parser> TriggerBox::input_parser;
|
||||||
PBD::ScopedConnectionList TriggerBox::static_connections;
|
PBD::ScopedConnectionList TriggerBox::static_connections;
|
||||||
PBD::ScopedConnection TriggerBox::midi_input_connection;
|
PBD::ScopedConnection TriggerBox::midi_input_connection;
|
||||||
std::shared_ptr<MidiPort> TriggerBox::current_input;
|
std::shared_ptr<MidiPort> TriggerBox::current_input;
|
||||||
@ -3068,6 +3068,7 @@ TriggerBox::init ()
|
|||||||
void
|
void
|
||||||
TriggerBox::static_init (Session & s)
|
TriggerBox::static_init (Session & s)
|
||||||
{
|
{
|
||||||
|
input_parser = std::shared_ptr<MIDI::Parser>(new MIDI::Parser); /* leak */
|
||||||
Config->ParameterChanged.connect_same_thread (static_connections, boost::bind (&TriggerBox::static_parameter_changed, _1));
|
Config->ParameterChanged.connect_same_thread (static_connections, boost::bind (&TriggerBox::static_parameter_changed, _1));
|
||||||
input_parser->any.connect_same_thread (midi_input_connection, boost::bind (&TriggerBox::midi_input_handler, _1, _2, _3, _4));
|
input_parser->any.connect_same_thread (midi_input_connection, boost::bind (&TriggerBox::midi_input_handler, _1, _2, _3, _4));
|
||||||
std::dynamic_pointer_cast<MidiPort> (s.trigger_input_port())->set_trace (input_parser);
|
std::dynamic_pointer_cast<MidiPort> (s.trigger_input_port())->set_trace (input_parser);
|
||||||
|
Loading…
Reference in New Issue
Block a user