Use multiple reader single writer locks for VST3

This would also need to be done on the plugin side.
This commit is contained in:
Robbert van der Helm
2021-12-28 18:51:14 +01:00
parent 2137d79229
commit 1507e4f574
4 changed files with 533 additions and 381 deletions
@@ -34,7 +34,7 @@ Vst3ContextMenuProxyImpl::~Vst3ContextMenuProxyImpl() noexcept {
bridge.send_message(
Vst3ContextMenuProxy::Destruct{.owner_instance_id = owner_instance_id(),
.context_menu_id = context_menu_id()});
bridge.unregister_context_menu(owner_instance_id(), context_menu_id());
bridge.unregister_context_menu(*this);
}
tresult PLUGIN_API
File diff suppressed because it is too large Load Diff
+20 -3
View File
@@ -18,6 +18,7 @@
#include <iostream>
#include <map>
#include <shared_mutex>
#include <string>
#include <public.sdk/source/vst/hosting/module.h>
@@ -319,8 +320,7 @@ class Vst3Bridge : public HostBridge {
* is called from the destructor of `Vst3ContextMenuProxyImpl` just before
* the object gets freed.
*/
void unregister_context_menu(size_t object_instance_id,
size_t context_menu_id);
void unregister_context_menu(Vst3ContextMenuProxyImpl& context_menu);
protected:
void close_sockets() override;
@@ -439,6 +439,15 @@ class Vst3Bridge : public HostBridge {
*/
size_t generate_instance_id() noexcept;
/**
* Fetch the plugin instance along with a lock valid for the instance's
* lifetime. This is mostly just to save some boilerplate everywhere. Use
* C++17's structured binding as syntactic sugar to not have to deal with
* the lock handle.
*/
std::pair<Vst3PluginInstance&, std::shared_lock<std::shared_mutex>>
get_instance(size_t instance_id) noexcept;
/**
* Sets up the shared memory audio buffers for a plugin instance plugin
* instance and return the configuration so the native plugin can connect to
@@ -504,7 +513,15 @@ class Vst3Bridge : public HostBridge {
* up.
*/
std::unordered_map<size_t, Vst3PluginInstance> object_instances;
std::mutex object_instances_mutex;
/**
* In theory all object handling is safe iff the host also doesn't do
* anything weird even without locks. The only time a data race can occur is
* when the host removes or inserts a plugin while also interacting with
* other plugins on different threads. Since the lock should never be
* contested, we should also not get a measurable performance penalty from
* making double sure nothing can go wrong.
*/
std::shared_mutex object_instances_mutex;
/**
* Used in `send_mutually_recursive_message()` to be able to execute