1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-11 23:54:18 +00:00

AudioPluginHost: Fix potential hang during plugin scanning

When dragging-and-dropping a plugin into the plugin host, it was
possible that the subprocess scanner could fail to send a response.
This would cause the superprocess to freeze, waiting for a reply.

With this change in place, the subprocess will always send a response
after scanning on the main thread.
This commit is contained in:
reuk 2023-11-20 16:26:01 +00:00
parent 123576bb2c
commit 968fa96dfc
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C

View file

@ -48,13 +48,15 @@ private:
if (mb.isEmpty())
return;
if (! doScan (mb))
{
{
const std::lock_guard<std::mutex> lock (mutex);
pendingBlocks.emplace (mb);
}
const std::lock_guard<std::mutex> lock (mutex);
if (const auto results = doScan (mb); ! results.isEmpty())
{
sendResults (results);
}
else
{
pendingBlocks.emplace (mb);
triggerAsyncUpdate();
}
}
@ -68,26 +70,17 @@ private:
{
for (;;)
{
const auto block = [&]() -> MemoryBlock
{
const std::lock_guard<std::mutex> lock (mutex);
const std::lock_guard<std::mutex> lock (mutex);
if (pendingBlocks.empty())
return {};
auto out = std::move (pendingBlocks.front());
pendingBlocks.pop();
return out;
}();
if (block.isEmpty())
if (pendingBlocks.empty())
return;
doScan (block);
sendResults (doScan (pendingBlocks.front()));
pendingBlocks.pop();
}
}
bool doScan (const MemoryBlock& block)
OwnedArray<PluginDescription> doScan (const MemoryBlock& block)
{
MemoryInputStream stream { block, false };
const auto formatName = stream.readString();
@ -106,20 +99,19 @@ private:
return nullptr;
}();
if (matchingFormat == nullptr
|| (! MessageManager::getInstance()->isThisTheMessageThread()
&& ! matchingFormat->requiresUnblockedMessageThreadDuringCreation (pd)))
OwnedArray<PluginDescription> results;
if (matchingFormat != nullptr
&& (MessageManager::getInstance()->isThisTheMessageThread()
|| matchingFormat->requiresUnblockedMessageThreadDuringCreation (pd)))
{
return false;
matchingFormat->findAllTypesForFile (results, identifier);
}
OwnedArray<PluginDescription> results;
matchingFormat->findAllTypesForFile (results, identifier);
sendPluginDescriptions (results);
return true;
return results;
}
void sendPluginDescriptions (const OwnedArray<PluginDescription>& results)
void sendResults (const OwnedArray<PluginDescription>& results)
{
XmlElement xml ("LIST");
@ -132,9 +124,6 @@ private:
std::mutex mutex;
std::queue<MemoryBlock> pendingBlocks;
// After construction, this will only be accessed by doScan so there's no need
// to worry about synchronisation.
AudioPluginFormatManager formatManager;
};