Why is this static? What happens if two different threads call into two different VST plugin instances at the same time?
If I remember correctly, it’s there to catch recursion in the event thread callbacks (e.g. host calls a plugin function, which calls hostIdle, which then calls another plugin function). That could happen between plugin instances, so it’s static, and should only happen on the event thread.
Hmm…I’m a little confused then. Check this out:
[code]int VSTPluginInstance::dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const
{
const ScopedLock sl (lock);
++insideVSTCallback;[/code]
What if there are two VSTPluginInstance objects, each in their own thread, going through dispatch()?
The only places that insideVSTCallback is actually checked are:
VSTPluginInstance::~VSTPluginInstance()
{
const ScopedLock sl (lock);
jassert (insideVSTCallback == 0);
and
case audioMasterIdle:
if (insideVSTCallback == 0 && MessageManager::getInstance()->isThisTheMessageThread())
{
++insideVSTCallback;
I almost always get that assertion in ~VSTPluginInstance(). I have multiple plugs in multiple threads.
For both of these cases it would make sense for the VSTPluginInstance to have insideVSTCallback be a non-static member. The treatment of loading the .DLL would have to be managed (it accesses insideVSTCallback but is not associated with an instance of VSTPluginInstance).
Thoughts?
hmm…do I have to do something special in my host application? I create the plugin on a separate dedicated thread (to avoid slowing down the audio i/o callback) and then I call the process function from the audio i/o callback.
How does the plugin gain access to the message thread? Do I have to add support for hostIdle ?
OH…
…okay I think I understand now Jules!
I believe what we need is to change
to
and add
to VSTPluginInstance(). Then, every member of VSTPluginInstance that currently does
should become
if (++insideVSTCallback == 1)
++globalInsideVSTCallback;
And of course the corresponding code for decrementing:
if (--insideVSTCallback == 0)
--globalInsideVSTCallback;
This will fix the assert in the destructor. The case for audioMasterIdle would use globalInsideVSTCallback instead of insideVSTCallback.
Whaddyathink?
Creating plugins on background threads can cause problems… I had a lot of trouble because Wavelab does that - see my rants about it on other threads.
Looking at it again, the safeguard could probably be implemented better - the whole point was to prevent the idle callbacks becoming recursive, so a thread-local variable would be ideal… Or maybe it could be used to protect a smaller section of the code, which won’t be called in a multi-threaded context. Will have a look.
Uuuuggghhh…I feel a headache coming on…is there a consolidated “best practices” for hosts I can read up on? Where are these threads?