diff --git a/CHANGELOG.md b/CHANGELOG.md index d6cf0066..aef78763 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ Versioning](https://semver.org/spec/v2.0.0.html). request a host callback while the host simultaneously tried to create another instance of the same plugin. This would result in a deadlock. An example of a plugin that triggered this is _PolyChrome DSP's McRocklin Suite_. +- Mutually recursive callbacks are now enabled for more CLAP lifetime function + calls. This was also needed to avoid a deadlock in _PolyChrome DSP's McRocklin + Suite_, as it changes its latency while being initialized. ### yabridgectl diff --git a/src/plugin/bridges/clap-impls/plugin-factory-proxy.cpp b/src/plugin/bridges/clap-impls/plugin-factory-proxy.cpp index 1e10b621..57e9269d 100644 --- a/src/plugin/bridges/clap-impls/plugin-factory-proxy.cpp +++ b/src/plugin/bridges/clap-impls/plugin-factory-proxy.cpp @@ -77,8 +77,9 @@ clap_plugin_factory_proxy::plugin_factory_create_plugin( } const clap::factory::plugin_factory::CreateResponse response = - self->bridge_.send_main_thread_message(clap::factory::plugin_factory::Create{ - .host = *host, .plugin_id = plugin_id}); + self->bridge_.send_mutually_recursive_main_thread_message( + clap::factory::plugin_factory::Create{.host = *host, + .plugin_id = plugin_id}); if (response.instance_id) { // This plugin proxy is tied to the instance ID created on the Wine // side. That way we can link function calls from the host to the diff --git a/src/plugin/bridges/clap-impls/plugin-proxy.cpp b/src/plugin/bridges/clap-impls/plugin-proxy.cpp index d78ba64c..d192b2b8 100644 --- a/src/plugin/bridges/clap-impls/plugin-proxy.cpp +++ b/src/plugin/bridges/clap-impls/plugin-proxy.cpp @@ -156,10 +156,12 @@ bool CLAP_ABI clap_plugin_proxy::plugin_init(const struct clap_plugin* plugin) { // plugin host so it can expose the same interfaces there. self->host_extensions_ = ClapHostExtensions(*self->host_); + // NOTE: McRocklin Suite changes the latency during the init call const clap::plugin::InitResponse response = - self->bridge_.send_main_thread_message(clap::plugin::Init{ - .instance_id = self->instance_id(), - .supported_host_extensions = self->host_extensions_.supported()}); + self->bridge_.send_mutually_recursive_main_thread_message( + clap::plugin::Init{.instance_id = self->instance_id(), + .supported_host_extensions = + self->host_extensions_.supported()}); // This determines which extensions the host is allowed to query in // `clap_plugin::get_extension()` @@ -175,7 +177,7 @@ clap_plugin_proxy::plugin_destroy(const struct clap_plugin* plugin) { // This will clean everything related to this instance up on the Wine plugin // host side - self->bridge_.send_main_thread_message( + self->bridge_.send_mutually_recursive_main_thread_message( clap::plugin::Destroy{.instance_id = self->instance_id()}); // And this deallocates and destroys `self` @@ -220,7 +222,7 @@ clap_plugin_proxy::plugin_deactivate(const struct clap_plugin* plugin) { assert(plugin && plugin->plugin_data); auto self = static_cast(plugin->plugin_data); - self->bridge_.send_main_thread_message( + self->bridge_.send_mutually_recursive_main_thread_message( clap::plugin::Deactivate{.instance_id = self->instance_id()}); } @@ -440,7 +442,7 @@ clap_plugin_proxy::ext_audio_ports_config_select(const clap_plugin_t* plugin, assert(plugin && plugin->plugin_data); auto self = static_cast(plugin->plugin_data); - return self->bridge_.send_main_thread_message( + return self->bridge_.send_mutually_recursive_main_thread_message( clap::ext::audio_ports_config::plugin::Select{ .instance_id = self->instance_id(), .config_id = config_id}); } @@ -489,7 +491,7 @@ bool CLAP_ABI clap_plugin_proxy::ext_gui_create(const clap_plugin_t* plugin, return false; } - return self->bridge_.send_main_thread_message( + return self->bridge_.send_mutually_recursive_main_thread_message( clap::ext::gui::plugin::Create{ .instance_id = self->instance_id(), // This will be translated to WIN32 on the Wine plugin host side @@ -501,7 +503,7 @@ void CLAP_ABI clap_plugin_proxy::ext_gui_destroy(const clap_plugin_t* plugin) { assert(plugin && plugin->plugin_data); auto self = static_cast(plugin->plugin_data); - self->bridge_.send_main_thread_message( + self->bridge_.send_mutually_recursive_main_thread_message( clap::ext::gui::plugin::Destroy{.instance_id = self->instance_id()}); }