Static Array<void*> activePlugins deleting MessageManager


#1

The 

static Array<void*> activePlugins

in the juce wrapper source files are giving me issues. In my plugin, other plugins can be instantiated. This is an example of my issue:

• instantiate my plugin as an AU in Logic Pro (the AU wrapper's activePlugins size = 1)

• instatiate a VST in my plugin (the VST wrapper's activePlugins size = 1)

• remove the VST that was just instantiated

    • create a MessageManagerLock

    • remove the VST instance

       • the VST wrapper's activePlugins size == 0, so shutdownJuce_GUI() is called

           • the MessageManager singleton instance is deleted.

       • continue cleaning up the VST, but wait! An assertion is hit because the Message thread is no longer locked even though we are still in the scope (and the same thread) where the MessageManagerLock above was declared.

Basically the MessageManager gets rebooted in the middle of a MessageManagerLock, invalidating the lock. Has anybody ran into this situation before? Is there an easy way into avoid shutdownJuce_GUI() in this scenerio ? 

 

 


#2

If you load a debug-build plugin inside a debug-build host, then the linker can mix-up the symbols when it gets loaded into memory, and the plugin can end up calling into private bits of the host.

Easy solution: strip symbols from either the plugin or host.


#3

Ah, I see. So the host and plugins are supposed to have unique copies of the static array?

Would the MessageManager be unique in this sense as well or is it shared?


#4

Yes, everything in a DLL should be internal except for the symbols that you choose to expose publicly. It's only an annoying quirk of the way the dynamic loader works that makes this happen when you have a debug build.


#5

Ah ok. Printing some things out helped out. I suppose it makes sense that you can't spawn a new message thread for every new dll :)


HOST: mm = 0x7fd201a2d200, threadWithLock = 0x0, messageThread = 0x7fff75992310
COMP: mm = 0x7fd2050a40b0, threadWithLock = 0x0, messageThread = 0x7fff75992310

So I guess it's always best to have only one debug build when working with dlls... Thanks for the tips!


#6

One more question,

I'm now running into a deadlock when attempting to delete a vst ui from a non-message thread. Is it possible to call VSTPluginWindow::closePluginWindow() from a non-message thread?

void closePluginWindow()
{ 
    if (isOpen)
    {
        JUCE_VST_LOG ("Closing VST UI: " + plugin.getName());
        isOpen = false;
        dispatch (effEditClose, 0, 0, 0, 0);
        stopTimer();
        ...

dispatch() creates a ScopedLock. A couple calls further into the stack it attempts to create a MessageManagerLock. However, the VSTPluginWindow timer is still running during all of this and in the timer callback it calls

plugin.dispatch (effEditIdle, 0, 0, 0, 0);

which attempts to grab that same ScopedLock.

So the other thread waits for the message thread to finish so it can create the MessageManagerLock, while the message thread is waiting for that ScopedLock to release.


#7

No, you should always close the UI from the message thread.


#8

Ok great thanks!

If it doesn't bloat the code perhaps a few assertions in there could save others some time.


#9

Sure, can add that!