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:
parent
4f7137cc08
commit
32a89090f6
3 changed files with 41 additions and 17 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue