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.v6.1.6
| @@ -115,6 +115,9 @@ public: | |||||
| */ | */ | ||||
| virtual bool isTrivialToScan() const = 0; | 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. | /** 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 | The path might be ignored, e.g. by AUs, which are found by the OS rather | ||||
| than manually. | than manually. | ||||
| @@ -61,6 +61,13 @@ public: | |||||
| bool canScanForPlugins() const override { return true; } | bool canScanForPlugins() const override { return true; } | ||||
| bool isTrivialToScan() const override { return false; } | 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<PluginDescription>&, const String& fileOrIdentifier) override; | void findAllTypesForFile (OwnedArray<PluginDescription>&, const String& fileOrIdentifier) override; | ||||
| bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; | bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; | ||||
| String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; | String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; | ||||
| @@ -387,10 +387,14 @@ public: | |||||
| Scanner (PluginListComponent& plc, AudioPluginFormat& format, const StringArray& filesOrIdentifiers, | Scanner (PluginListComponent& plc, AudioPluginFormat& format, const StringArray& filesOrIdentifiers, | ||||
| PropertiesFile* properties, bool allowPluginsWhichRequireAsynchronousInstantiation, int threads, | PropertiesFile* properties, bool allowPluginsWhichRequireAsynchronousInstantiation, int threads, | ||||
| const String& title, const String& text) | 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), | pathChooserWindow (TRANS("Select folders to scan..."), String(), MessageBoxIconType::NoIcon), | ||||
| progressWindow (title, text, MessageBoxIconType::NoIcon), | progressWindow (title, text, MessageBoxIconType::NoIcon), | ||||
| numThreads (threads), allowAsync (allowPluginsWhichRequireAsynchronousInstantiation) | |||||
| numThreads (format.canScanOnBackgroundThread() ? threads : 0), | |||||
| allowAsync (format.canScanOnBackgroundThread() && allowPluginsWhichRequireAsynchronousInstantiation) | |||||
| { | { | ||||
| FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); | FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); | ||||
| @@ -443,7 +447,7 @@ private: | |||||
| FileSearchPathListComponent pathList; | FileSearchPathListComponent pathList; | ||||
| String pluginBeingScanned; | String pluginBeingScanned; | ||||
| double progress = 0; | double progress = 0; | ||||
| int numThreads; | |||||
| const int numThreads; | |||||
| bool allowAsync, finished = false, timerReentrancyCheck = false; | bool allowAsync, finished = false, timerReentrancyCheck = false; | ||||
| std::unique_ptr<ThreadPool> pool; | std::unique_ptr<ThreadPool> pool; | ||||