In my host vst plugin I have an AudioProcessorGraph that can load other vst’s. Say I load a child vst into the graph, open the child’s ui, and then remove the host vst. This causes a BAD_ACCESS in the destructor of the ScopedAutoReleasePool that gets destroyed at the end of ~JuceVSTWrapper():
I’ve narrowed it down to the graph’s destructor where it calls clearRenderingSequence() & deletes all the graph ops. If I prevent the ProcessBufferOp that’s associated with the child vst from being deleted here the crash does not occur (but assume would then leak).
I would guess that there’s some sort of double ownership going on here and something is getting deleted twice…
The really odd part is that the crash does not occur if the child vst’s ui is not instantiated.
Does anybody have tips on how to debug with an NSAutoReleasePool? What exactly is the purpose of having such a pool in ~JuceVSTWrapper()?
Looks like it might be somehow trying to release a dead object… That’s not supposed to be possible in obj-C, but I’ve seen similar things when you try to delete plugins without giving them enough time to shut down before their DLL is unloaded.
Maybe try modifying your code so that when deleting a plugin, you first remove its window, stop it playing, then wait a second before deleting the plugin itself. (You need to keep the event thread running while you wait, i.e. use a Timer or something asynchronous, to give it chance to clean up its UI detritis)
Hmm, how exactly do I pause the event thread to let it run other messages when all of this deletion process is occurring on the event thread itself? Is there some way to “freeze” the current message for a period of time?
If it’s your host then you don’t need to use hacks like runDispatchLoopUntil. Like I said above, you can do it cleanly, and just use a Timer or something to delete the plugin later.
My host is a plugin itself, so I’m competing with all the shutdownJuce_GUI() & activePlugins arrays in the plugin wrapper code files. It seems that any timers running go dead when the gui is shutdown.
Why wouldn’t runDispatchLoopUntil() work in this context?
It seems that there’s not really an elegant way to solve this issue for plugins that are hosting other plugins.
The main issue is that the host sort of expects all of the plugin’s allocations to be freed once the callback that deleted the plugin finishes.
Once deleted by the host, there’s no guarantee that a plugin’s instruction code will still be around in memory, is there? I’ve tried creating an “async deleter” object on the heap that uses the Timer class to wait a millisecond and then deletes the plugin. It seems to work but I feel like it’s just a matter of timing and in many use cases would probably crash (eg when say the host quickly deletes one instance and creates another via switching projects)
Does anybody else have any ideas for such an issue?
Hmm, I switched gigs shortly after so I don’t have access to that particular code anymore. I don’t think we ever came up with a more elegant solution, though.