mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +02:00
Use multiple reader single writer locks for VST3
This would also need to be done on the plugin side.
This commit is contained in:
@@ -31,6 +31,9 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
- Fixed VST3 connection point proxies not being disconnected properly. This code
|
- Fixed VST3 connection point proxies not being disconnected properly. This code
|
||||||
path is not being used for any of the current Linux VST3 hosts, so this did
|
path is not being used for any of the current Linux VST3 hosts, so this did
|
||||||
not yet cause any issues.
|
not yet cause any issues.
|
||||||
|
- Rewritten the VST3 object handling to prevent some theoretical data races when
|
||||||
|
the host inserts or removes plug instances while other instances of that
|
||||||
|
plugin are processing audio.
|
||||||
|
|
||||||
### Packaging notes
|
### Packaging notes
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Vst3ContextMenuProxyImpl::~Vst3ContextMenuProxyImpl() noexcept {
|
|||||||
bridge.send_message(
|
bridge.send_message(
|
||||||
Vst3ContextMenuProxy::Destruct{.owner_instance_id = owner_instance_id(),
|
Vst3ContextMenuProxy::Destruct{.owner_instance_id = owner_instance_id(),
|
||||||
.context_menu_id = context_menu_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
|
tresult PLUGIN_API
|
||||||
|
|||||||
+509
-377
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <public.sdk/source/vst/hosting/module.h>
|
#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
|
* is called from the destructor of `Vst3ContextMenuProxyImpl` just before
|
||||||
* the object gets freed.
|
* the object gets freed.
|
||||||
*/
|
*/
|
||||||
void unregister_context_menu(size_t object_instance_id,
|
void unregister_context_menu(Vst3ContextMenuProxyImpl& context_menu);
|
||||||
size_t context_menu_id);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void close_sockets() override;
|
void close_sockets() override;
|
||||||
@@ -439,6 +439,15 @@ class Vst3Bridge : public HostBridge {
|
|||||||
*/
|
*/
|
||||||
size_t generate_instance_id() noexcept;
|
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
|
* Sets up the shared memory audio buffers for a plugin instance plugin
|
||||||
* instance and return the configuration so the native plugin can connect to
|
* instance and return the configuration so the native plugin can connect to
|
||||||
@@ -504,7 +513,15 @@ class Vst3Bridge : public HostBridge {
|
|||||||
* up.
|
* up.
|
||||||
*/
|
*/
|
||||||
std::unordered_map<size_t, Vst3PluginInstance> object_instances;
|
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
|
* Used in `send_mutually_recursive_message()` to be able to execute
|
||||||
|
|||||||
Reference in New Issue
Block a user