#include "PluginScannerSubprocess.hpp" #include "common.h" #include "DisableCrashReporter.hpp" using namespace juce; PluginScannerSubprocess::PluginScannerSubprocess() { formatManager.addDefaultFormats(); } bool PluginScannerSubprocess::initialiseFromCommandLine (const String& commandLine, const String& commandLineUniqueID, int timeoutMs) { auto res = ChildProcessWorker::initialiseFromCommandLine(commandLine, commandLineUniqueID, timeoutMs); if(res) { disableCrashReporter(); } return res; } void PluginScannerSubprocess::handleMessageFromCoordinator (const MemoryBlock& mb) { if (mb.isEmpty()) return; const std::lock_guard lock (mutex); if (const auto results = doScan(mb); !results.isEmpty()) { sendResults(results); } else { pendingBlocks.emplace (mb); triggerAsyncUpdate(); } } void PluginScannerSubprocess::handleConnectionLost() { // we really don't want these processes to stick around and forkbomb the user's machine exitImmediately(); } void PluginScannerSubprocess::handleAsyncUpdate() { for (;;) { const std::lock_guard lock (mutex); if (pendingBlocks.empty()) return; sendResults(doScan(pendingBlocks.front())); pendingBlocks.pop(); } } OwnedArray PluginScannerSubprocess::doScan (const MemoryBlock& block) { using clock_t = std::chrono::high_resolution_clock; auto startTime = clock_t::now(); MemoryInputStream stream { block, false }; const auto formatName = stream.readString(); const auto identifier = stream.readString(); PluginDescription pd; pd.fileOrIdentifier = identifier; pd.uniqueId = pd.deprecatedUid = 0; const auto matchingFormat = [&]() -> AudioPluginFormat* { for (auto* format : formatManager.getFormats()) if (format->getName() == formatName) return format; return nullptr; }(); OwnedArray results; if (matchingFormat != nullptr && (MessageManager::getInstance()->isThisTheMessageThread() || matchingFormat->requiresUnblockedMessageThreadDuringCreation (pd))) { matchingFormat->findAllTypesForFile (results, identifier); auto dt = clock_t::now() - startTime; std::cerr << "findAllTypesForFile (pid " << getpid() << ") " << identifier << " has " << results.size() << " types (in " << (float)std::chrono::duration_cast(dt).count() / 1000.f << " ms)\n"; } #ifndef _MSC_VER Process::setDockIconVisible(false); #endif return results; } void PluginScannerSubprocess::sendResults (const OwnedArray& results) { XmlElement xml ("LIST"); for (const auto& desc : results) xml.addChildElement (desc->createXml().release()); const auto str = xml.toString(); sendMessageToCoordinator ({ str.toRawUTF8(), str.getNumBytesAsUTF8() }); }