From d286e690b22478e6d09c389ded236d3e4cf62245 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 6 Oct 2021 16:20:17 +0100 Subject: [PATCH] PluginListComponent: Disallow scanning VST3 plugins on background threads Native Instrument VST3s (I tested Kontakt and Supercharger) crash when the bundleEntry function is called from a background thread on macOS. This change disables scanning for VST3 plugins on a background thread using the PluginListComponent, to allow loading these plugins in the AudioPluginHost. I can't find any "official" word on whether the bundleEntry and bundleExit functions should be guaranteed to be made from the main thread. However, the VST3PluginTestHost app seems to call these functions exclusively from the main thread. --- .../format/juce_AudioPluginFormat.h | 3 +++ .../format_types/juce_VST3PluginFormat.h | 7 +++++++ .../scanning/juce_PluginListComponent.cpp | 10 +++++++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h index f3bc826820..7bd45452f2 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h @@ -115,6 +115,9 @@ public: */ virtual bool isTrivialToScan() const = 0; + /** Should return true if plugins in this format can be scanned on a background thread. */ + virtual bool canScanOnBackgroundThread() const { return true; } + /** Searches a suggested set of directories for any plugins in this format. The path might be ignored, e.g. by AUs, which are found by the OS rather than manually. diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h index 9c2be59493..e58736d96c 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h @@ -61,6 +61,13 @@ public: bool canScanForPlugins() const override { return true; } bool isTrivialToScan() const override { return false; } + /** Although there doesn't seem to be any official documentation on the matter, + Native Instruments Kontakt VST3 crashes on macOS when its bundleEntry is called on a + background thread. To allow this plugin (and other ones with similar problems) to be + discovered, it's a good idea to scan VST3 plugins on the main thread. + */ + bool canScanOnBackgroundThread() const override { return false; } + void findAllTypesForFile (OwnedArray&, const String& fileOrIdentifier) override; bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 5f6c8a3a7a..103a53546d 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -387,10 +387,14 @@ public: Scanner (PluginListComponent& plc, AudioPluginFormat& format, const StringArray& filesOrIdentifiers, PropertiesFile* properties, bool allowPluginsWhichRequireAsynchronousInstantiation, int threads, const String& title, const String& text) - : owner (plc), formatToScan (format), filesOrIdentifiersToScan (filesOrIdentifiers), propertiesToUse (properties), + : owner (plc), + formatToScan (format), + filesOrIdentifiersToScan (filesOrIdentifiers), + propertiesToUse (properties), pathChooserWindow (TRANS("Select folders to scan..."), String(), MessageBoxIconType::NoIcon), progressWindow (title, text, MessageBoxIconType::NoIcon), - numThreads (threads), allowAsync (allowPluginsWhichRequireAsynchronousInstantiation) + numThreads (format.canScanOnBackgroundThread() ? threads : 0), + allowAsync (format.canScanOnBackgroundThread() && allowPluginsWhichRequireAsynchronousInstantiation) { FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); @@ -443,7 +447,7 @@ private: FileSearchPathListComponent pathList; String pluginBeingScanned; double progress = 0; - int numThreads; + const int numThreads; bool allowAsync, finished = false, timerReentrancyCheck = false; std::unique_ptr pool;