From e3cae805807dd512fe9c7a55e81486b87e9cb6ed Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 18 Apr 2020 10:04:21 +0200 Subject: [PATCH] Audio/MidiJack: Fix invalid read: (3) of #5408 This atomically unsets the MidiJack reference in AudioJack right before MidiJack is destroyed. This avoids AudioJack using a destroyed MidiJack object. --- include/AudioJack.h | 3 ++- src/core/audio/AudioJack.cpp | 4 ++-- src/core/midi/MidiJack.cpp | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/AudioJack.h b/include/AudioJack.h index 9c412e202..2006906af 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -58,6 +58,7 @@ public: // the jack callback is handled here, we call the midi client so that it can read // it's midi data during the callback AudioJack * addMidiClient(MidiJack *midiClient); + void removeMidiClient(void) { m_midiClient = nullptr; } jack_client_t * jackClient() {return m_client;}; inline static QString name() @@ -109,7 +110,7 @@ private: bool m_active; std::atomic m_stopped; - MidiJack *m_midiClient; + std::atomic m_midiClient; QVector m_outputPorts; jack_default_audio_sample_t * * m_tempOutBufs; surroundSampleFrame * m_outBuf; diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index ba0daae94..1c1628a04 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -346,8 +346,8 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) // add to the following sound processing if( m_midiClient && _nframes > 0 ) { - m_midiClient->JackMidiRead(_nframes); - m_midiClient->JackMidiWrite(_nframes); + m_midiClient.load()->JackMidiRead(_nframes); + m_midiClient.load()->JackMidiWrite(_nframes); } for( int c = 0; c < channels(); ++c ) diff --git a/src/core/midi/MidiJack.cpp b/src/core/midi/MidiJack.cpp index 664e1f16d..f71ef4a4c 100644 --- a/src/core/midi/MidiJack.cpp +++ b/src/core/midi/MidiJack.cpp @@ -116,6 +116,9 @@ MidiJack::~MidiJack() { if(jackClient()) { + // remove ourselves first (atomically), so we will not get called again + m_jackAudio->removeMidiClient(); + if( jack_port_unregister( jackClient(), m_input_port) != 0){ printf("Failed to unregister jack midi input\n"); }