Static int insideVSTCallback = 0;


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);


What if there are two VSTPluginInstance objects, each in their own thread, going through dispatch()?

The only places that insideVSTCallback is actually checked are:

    const ScopedLock sl (lock);
    jassert (insideVSTCallback == 0);


    case audioMasterIdle:
        if (insideVSTCallback == 0 && MessageManager::getInstance()->isThisTheMessageThread())

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).



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 ?



…okay I think I understand now Jules!

I believe what we need is to change


and add

to VSTPluginInstance(). Then, every member of VSTPluginInstance that currently does

should become

if (++insideVSTCallback == 1)

And of course the corresponding code for decrementing:

if (--insideVSTCallback == 0)

This will fix the assert in the destructor. The case for audioMasterIdle would use globalInsideVSTCallback instead of insideVSTCallback.



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?