1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

BLOCKS: Fix potential race conditions in Topology

This commit is contained in:
dimitri 2018-12-18 12:30:39 +00:00 committed by ed
parent 4f7137cc08
commit 32a89090f6
3 changed files with 41 additions and 17 deletions

View file

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

View file

@ -70,10 +70,10 @@ private:
static constexpr size_t numFirmwareApps = 3;
BlocksProtocol::VersionNumber result[numFirmwareApps];
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()
@ -83,17 +83,17 @@ private:
{ 0xf0, 0x00, 0x21, 0x10, 0x47, 0x03, 0x01, 0xf7 }, // Stm32
{ 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)
{
if (currentRequest >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength)
if (currentRequest.get() >= numFirmwareApps || size < 1 || size - 1 > VersionNumber::maxLength)
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;

View file

@ -63,11 +63,13 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection,
void addListener (Listener* l)
{
juce::ScopedLock scopedLock (criticalSecton);
listeners.add (l);
}
void removeListener (Listener* l)
{
juce::ScopedLock scopedLock (criticalSecton);
listeners.remove (l);
}
@ -90,20 +92,27 @@ struct MIDIDeviceConnection : public PhysicalTopologySource::DeviceConnection,
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);
listeners.call ([&] (Listener& l) { l.handleIncomingMidiMessage (message); });
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); });
}
}
std::unique_ptr<juce::MidiInput> midiInput;
std::unique_ptr<juce::MidiOutput> midiOutput;
juce::CriticalSection criticalSecton;
private:
juce::ListenerList<Listener> listeners;
std::unique_ptr<juce::InterProcessLock> interprocessLock;