-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple instances of lv2 camomile freezes reaper and carla on 32 bit linux mint 19. #286
Comments
I am also seeing the same problem with Ardour: two instances of the same Camomile LV2 plugin will work fine, but having two different Camomile plugins causes Ardour to hang. Environment
Some debug output from ArdourI had a project in Ardour which already used an instance of AlmondOrgan (LV2). That works well. When I add an instance of the Castafiore effect (also LV2) to an audio track, Ardour freezes/hangs. At the same time, Ardour's terminal output is filled with thousands of repetitions of this message:
Basic investigation: what assertion is failing?The error message refers to this part of bool MessageManager::Lock::tryAcquire (bool lockIsMandatory) const noexcept
{
auto* mm = MessageManager::instance;
if (mm == nullptr)
{
jassertfalse;
return false;
}
...
} I don't know the JUCE code well, but the following around line 420 is suspicious. It loops over (a wrapper method of) the bool MessageManagerLock::attemptLock (Thread* threadToCheck, ThreadPoolJob* jobToCheck)
{
...
// tryEnter may have a spurious abort (return false) so keep checking the condition
while ((threadToCheck == nullptr || ! threadToCheck->threadShouldExit())
&& (jobToCheck == nullptr || ! jobToCheck->shouldExit()))
{
if (mmLock.tryEnter())
break;
}
...
} Any ideas or comments would be appreciated because I'd like to get this bug fixed! |
I added a few lines of debugging code to the Making use of backtrace, I also obtained a stack-trace showing (sort of) how
This shows that, when an LV2 plugin is initialised, a {
const MessageManagerLock mmLock;
filter = std::unique_ptr<AudioProcessor>(createPluginFilterOfType (AudioProcessor::wrapperType_LV2));
} My debugging suggests that, when a second Camomile plugin is initialised by the DAW, the construction of the |
Here is how (I think) the MessageManager is created for an LV2 plugin. Around line 1500 of private:
#if JUCE_LINUX
SharedResourcePointer<SharedMessageThread> msgThread;
#else
SharedResourcePointer<ScopedJuceInitialiser_GUI> sharedJuceGUI;
#endif That struct SharedMessageThread : public Thread
{
void run() override
{
// ...
MessageManager::getInstance()->setCurrentThreadAsMessageThread();
// ...
while ((! threadShouldExit()) && MessageManager::getInstance()->runDispatchLoopUntil (250))
{}
}
} Debugging shows that:
Despite the fact that all plugin instances share the SharedMessageThread, the MessageManager instance cannot be found by the second plugin instance - calling A question
|
I have found a fix, but not the fix... I changed line 133 of -set_target_properties(Camomile_LV2 PROPERTIES PREFIX "")
+set_target_properties(Camomile_LV2 PROPERTIES PREFIX "" CXX_STANDARD 20) and made the SharedMessageThread...well...not shared! The change applies to - SharedResourcePointer<SharedMessageThread> msgThread;
+ SharedMessageThread msgThread; Multiple different Camomile plugins can now be loaded, and the plugins are working. Once, when I closed my Ardour session after inserting and deleting multiple Camomile plugins, it froze, but since then I have worked on the session several times and it has always closed without issue. |
After trying a few things out, I've discovered that a message thread created via This seems really odd to me...I would have expected a SharedResourcePointer to be shared across instances of the same plugin, but it is somehow being shared across all instances of all Camomile plugins. How is it being shared? Well...
The second line of output seems to refer to a variable in a method of the SharedResourcePointer class. The
That explains it - this "holder", which keeps track of the object held by the SharedResourcePointer, will have the same value throughout the entire process - meaning the whole of Ardour? The question now is: why the fu-...I mean, how did this end up being "unique global", and can this be changed? |
It wasn't easy to find, but this GCC bug report seems to be the final piece in the puzzle: Problem with C++ unique symbols in plugins The answer is that specifying Raising a PR. |
…ierreguillot#286) This issue was ultimately caused by an object buried in the JUCE code having an inappopriate scope - GCC made the object a "unique global symbol", which means there is only one instance across the current process. When multiple plugins were loaded, they all shared this instance, but did not share other relevant objects (from the JUCE code), causing havoc. The fix is to ban the compiler from marking symbols as "unique global". Also set the C++ standard to be C++20 for the Camomile_LV2 meta-plugin, in line with the other meta-plugins.
…ierreguillot#286) This issue was ultimately caused by an object buried in the JUCE code having an inappropriate scope - GCC made the object a "unique global symbol", which means there is only one instance across the current process. When multiple plugins were loaded, they all shared this instance, but did not share other relevant objects (from the JUCE code), causing havoc. The fix is to ban the compiler from marking symbols as "unique global". Also set the C++ standard to be C++20 for the Camomile_LV2 meta-plugin, in line with the other meta-plugins.
…ierreguillot#286) This issue was ultimately caused by an object buried in the JUCE code having an inappropriate scope - GCC made the object a "unique global symbol", which means there is only one instance across the current process. When multiple plugins were loaded, they all shared this instance, but did not share other relevant objects (from the JUCE code), causing havoc. The fix is to ban GCC from marking symbols as "unique global". Also set the C++ standard to be C++20 for the Camomile_LV2 meta-plugin, in line with the other meta-plugins.
…286) This issue was ultimately caused by an object buried in the JUCE code having an inappropriate scope - GCC made the object a "unique global symbol", which means there is only one instance across the current process. When multiple plugins were loaded, they all shared this instance, but did not share other relevant objects (from the JUCE code), causing havoc. The fix is to ban GCC from marking symbols as "unique global". Also set the C++ standard to be C++20 for the Camomile_LV2 meta-plugin, in line with the other meta-plugins.
I guess this is fixed, isn't it? |
(in the plugin by distrho called ildaeli when I enable 'run in bridge mode' I am able to load multiple instances. Also in reaper when I run carla as dedicated process I am able to load multiple instances)
Whether or not the same issue is present in vst3 idk because those don't load at all but I'll make a separate issue for that. It happens in Carla and reaper, both latest versions on 32 bit linux mint 19. it happens wirh all plugins generated through camomile. Multiple instances of the same plugin does not cause this issue. Carla freezes before it logs anything about the second instance, but here's a log anyway:
The text was updated successfully, but these errors were encountered: