Browse Source

BLOCKS: Fix potential race conditions in Topology

tags/2021-05-28
dimitri ed 6 years ago
parent
commit
32a89090f6
3 changed files with 41 additions and 17 deletions
  1. +19
    -4
      modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp
  2. +6
    -6
      modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp
  3. +16
    -7
      modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp

+ 19
- 4
modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp View File

@@ -88,14 +88,20 @@ struct ConnectedDeviceGroup : private juce::AsyncUpdater,
ConnectedDeviceGroup (Detector& d, const juce::String& name, PhysicalTopologySource::DeviceConnection* connection) ConnectedDeviceGroup (Detector& d, const juce::String& name, PhysicalTopologySource::DeviceConnection* connection)
: detector (d), deviceName (name), deviceConnection (connection) : detector (d), deviceName (name), deviceConnection (connection)
{ {
deviceConnection->handleMessageFromDevice = [this] (const void* data, size_t dataSize)
{
this->handleIncomingMessage (data, dataSize);
};
if (auto midiDeviceConnection = static_cast<MIDIDeviceConnection*> (deviceConnection.get())) if (auto midiDeviceConnection = static_cast<MIDIDeviceConnection*> (deviceConnection.get()))
{
depreciatedVersionReader = std::make_unique<DepreciatedVersionReader> (*midiDeviceConnection); depreciatedVersionReader = std::make_unique<DepreciatedVersionReader> (*midiDeviceConnection);
juce::ScopedLock lock (midiDeviceConnection->criticalSecton);
setMidiMessageCallback();
}
else
{
setMidiMessageCallback();
}
startTimer (200); startTimer (200);
sendTopologyRequest(); sendTopologyRequest();
} }
@@ -372,6 +378,15 @@ private:
Block::UID masterBlock = 0; Block::UID masterBlock = 0;
//==============================================================================
void setMidiMessageCallback()
{
deviceConnection->handleMessageFromDevice = [this] (const void* data, size_t dataSize)
{
this->handleIncomingMessage (data, dataSize);
};
}
//============================================================================== //==============================================================================
juce::Time lastTopologyRequestTime, lastTopologyReceiveTime; juce::Time lastTopologyRequestTime, lastTopologyReceiveTime;
int numTopologyRequestsSent = 0; int numTopologyRequestsSent = 0;


+ 6
- 6
modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp View File

@@ -70,10 +70,10 @@ private:
static constexpr size_t numFirmwareApps = 3; static constexpr size_t numFirmwareApps = 3;
BlocksProtocol::VersionNumber result[numFirmwareApps]; BlocksProtocol::VersionNumber result[numFirmwareApps];
MIDIDeviceConnection& deviceConnection; MIDIDeviceConnection& deviceConnection;
size_t currentRequest = 0;
juce::Atomic<size_t> currentRequest = 0;
//============================================================================== //==============================================================================
bool allRequestsComplete() const { return currentRequest >= numFirmwareApps; }
bool allRequestsComplete() const { return currentRequest.get() >= numFirmwareApps; }
//============================================================================== //==============================================================================
void makeNextRequest() void makeNextRequest()
@@ -83,17 +83,17 @@ private:
{ 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x01, 0xf7 }, // Stm32 { 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x01, 0xf7 }, // Stm32
{ 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x03, 0xf7 }}; // Bootloader { 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x03, 0xf7 }}; // Bootloader
deviceConnection.sendMessageToDevice (&requests[currentRequest][0], requestSize);
deviceConnection.sendMessageToDevice (&requests[currentRequest.get()][0], requestSize);
} }
//============================================================================== //==============================================================================
void processVersionMessage (const uint8* data, const size_t size) void processVersionMessage (const uint8* data, const size_t size)
{ {
if (currentRequest >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength)
if (currentRequest.get() >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength)
return; return;
result[currentRequest].length = uint8 (size - 1);
memcpy (result[currentRequest].data, data, result[currentRequest].length);
result[currentRequest.get()].length = uint8 (size - 1);
memcpy (result[currentRequest.get()].data, data, result[currentRequest.get()].length);
++currentRequest; ++currentRequest;


+ 16
- 7
modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp View File

@@ -63,11 +63,13 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection,
void addListener (Listener* l) void addListener (Listener* l)
{ {
juce::ScopedLock scopedLock (criticalSecton);
listeners.add (l); listeners.add (l);
} }
void removeListener (Listener* l) void removeListener (Listener* l)
{ {
juce::ScopedLock scopedLock (criticalSecton);
listeners.remove (l); listeners.remove (l);
} }
@@ -90,20 +92,27 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection,
void handleIncomingMidiMessage (juce::MidiInput*, const juce::MidiMessage& message) override void handleIncomingMidiMessage (juce::MidiInput*, const juce::MidiMessage& message) override
{ {
const auto data = message.getRawData();
const int dataSize = message.getRawDataSize();
const int bodySize = dataSize - (int) (sizeof (BlocksProtocol::roliSysexHeader) + 1);
juce::ScopedTryLock lock (criticalSecton);
if (bodySize > 0 && memcmp (data, BlocksProtocol::roliSysexHeader, sizeof (BlocksProtocol::roliSysexHeader)) == 0)
if (handleMessageFromDevice != nullptr)
handleMessageFromDevice (data + sizeof (BlocksProtocol::roliSysexHeader), (size_t) bodySize);
if (lock.isLocked())
{
const auto data = message.getRawData();
const int dataSize = message.getRawDataSize();
const int bodySize = dataSize - (int) (sizeof (BlocksProtocol::roliSysexHeader) + 1);
if (bodySize > 0 && memcmp (data, BlocksProtocol::roliSysexHeader, sizeof (BlocksProtocol::roliSysexHeader)) == 0)
if (handleMessageFromDevice != nullptr)
handleMessageFromDevice (data + sizeof (BlocksProtocol::roliSysexHeader), (size_t) bodySize);
listeners.call ([&] (Listener& l) { l.handleIncomingMidiMessage (message); });
listeners.call ([&] (Listener& l) { l.handleIncomingMidiMessage (message); });
}
} }
std::unique_ptr<juce::MidiInput> midiInput; std::unique_ptr<juce::MidiInput> midiInput;
std::unique_ptr<juce::MidiOutput> midiOutput; std::unique_ptr<juce::MidiOutput> midiOutput;
juce::CriticalSection criticalSecton;
private: private:
juce::ListenerList<Listener> listeners; juce::ListenerList<Listener> listeners;
std::unique_ptr<juce::InterProcessLock> interprocessLock; std::unique_ptr<juce::InterProcessLock> interprocessLock;


Loading…
Cancel
Save