I found that using plugin groups with the BBC Spitfire plugins can get
rid of all latency spikes I was getting when playing notes on 30
instances of them at once. After doing so the overall thread count
dropped from 332 down to 128.
MainContext is now basically just a wrapper with a simple event loop
implementation so it's not really necessary, but having a separate type
for the 'main' IO context still makes everything much clearer.
GroupHost::running() would sometimes cause plugins to get terminated
prematurely when connecting to another plugin's group host process since
the plugin's own group host process has exited.
This will also cause plugins to update their editors at 60 FPS. This was
kept at a lower value for performance reasons, but since the message
loop now no longer blocks event handling we can safely increase this.
This will double the amount of resources spent on drawing, but since
audio processing in a real world scenario almost never utilizes all
cores anyways this should not be an issue.
Since it does something way more involved than
`SocketHandler::{send,receive_multi}`, and that makes it a bit confusing
if you don't already know about that (and even if you do).
This was how it originally worked (and how it should work, since
otherwise there's no reason to reuse buffers), but for some reason this
got removed at some point.
This way the sockets can be destroyed before the threads, and we can
safely wait for the threads to shut down. I initially had Win32Thread
imitate std::jthread's join-on-destruct, but that was causing group
processes to hang. Now we can safely add that back again, and this will
fix some spurious segfaults during plugin scans when using plugin groups
containing a massive amount of plugins.
This will require more testing of course, but I think it should be safe.
This would increase the potential maximal throughput in group hosts
significantly.
std::function does not allow non-movable lambdas, so capturing by move
doesn't work there. And the old solution of course has issues with
dangling pointers (but because this is C++ the compiler still thinks
it's A-Ok).