In some situations, it’s necessary to have a timer or idle callback which is called regularly on the main thread. For instance, latency changes are reported by calling IComponentHandler::restartComponent
, and according to both the documentation for that method and the “VST 3 threading model” section in the documentation, restartComponent
must be called from the main thread. So, for instance, if a plugin needs to initiate a latency change from within a call to process
, it must somehow communicate the latency change to the main thread and report it there. For a plugin with a separate audio processor and edit controller, this will involve the use of IConnectionPoint::notify
, and for a single-component effect, this will involve a lock-free queue or something equivalent.
On Windows and macOS, there are platform APIs which make it possible to set up a timer callback on the main thread. On Linux, it’s possible to do the same thing while the GUI is open using the IRunLoop
API, but there is simply no way to achieve this while the GUI is closed. As a result, in scenarios like the above, plugins have to resort to violating the VST 3 threading rules and calling IComponentHandler::restartComponent
from a separate background thread. This is what JUCE does in this case.
In my opinion, VST 3’s Linux support cannot be considered complete without providing some mechanism for running code on the main thread when the GUI is not open. I think this could be done in a number of different ways, but some possible solutions might look like:
- Requiring that the host’s
IComponentHandler
object (or theIHostApplication
object) implementIRunLoop
, in addition to theIPlugFrame
object - An “idle callback” interface for the plugin’s edit controller, which hosts are required to call regularly on the main thread
- An interface which can be used from any thread to request a callback on the main thread, to be implemented by the host’s
IComponentHandler
object (or theIHostApplication
object)