Enable mutual recursion for all CLAP callbacks

This fixes Surge XT. It would otherwise deadlock when it tried to do a
parameter rescan on first load.
This commit is contained in:
Robbert van der Helm
2022-10-08 23:49:48 +02:00
parent 6979805773
commit f8399f26b5
2 changed files with 27 additions and 22 deletions
@@ -291,6 +291,9 @@ clap_host_proxy::ext_params_rescan(const clap_host_t* host,
assert(host && host->host_data); assert(host && host->host_data);
auto self = static_cast<const clap_host_proxy*>(host->host_data); auto self = static_cast<const clap_host_proxy*>(host->host_data);
// NOTE: This one in particular needs the mutual recursion because Surge XT
// calls this function immediately when inserting, and when the host
// opens the GUI at the same time this would otherwise deadlock
self->bridge_.send_mutually_recursive_main_thread_message( self->bridge_.send_mutually_recursive_main_thread_message(
clap::ext::params::host::Rescan{ clap::ext::params::host::Rescan{
.owner_instance_id = self->owner_instance_id(), .flags = flags}); .owner_instance_id = self->owner_instance_id(), .flags = flags});
+24 -22
View File
@@ -355,9 +355,11 @@ void ClapBridge::run() {
-> clap::ext::gui::plugin::IsApiSupported::Response { -> clap::ext::gui::plugin::IsApiSupported::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ // See below and the comment in `host-proxy.cpp` for why this is
.run_in_context([&, plugin = instance.plugin.get(), // sprinkled all over the place
gui = instance.extensions.gui]() { return do_mutual_recursion_on_gui_thread(
[&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() {
// It's a bit unnecessary to bridge the entire // It's a bit unnecessary to bridge the entire
// `is_api_supported()` function since we'll only bridge // `is_api_supported()` function since we'll only bridge
// a single config (non-floating, X11), but this is // a single config (non-floating, X11), but this is
@@ -374,16 +376,15 @@ void ClapBridge::run() {
request.is_floating); request.is_floating);
break; break;
} }
}) });
.get();
}, },
[&](const clap::ext::gui::plugin::Create& request) [&](const clap::ext::gui::plugin::Create& request)
-> clap::ext::gui::plugin::Create::Response { -> clap::ext::gui::plugin::Create::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() { gui = instance.extensions.gui]() {
// We don't need to do anything here yet. The actual // We don't need to do anything here yet. The actual
// window is created at the final `.set_parent()` call. // window is created at the final `.set_parent()` call.
// Like the above function, we'll translate the API type // Like the above function, we'll translate the API type
@@ -396,25 +397,23 @@ void ClapBridge::run() {
request.is_floating); request.is_floating);
break; break;
} }
}) });
.get();
}, },
[&](const clap::ext::gui::plugin::Destroy& request) [&](const clap::ext::gui::plugin::Destroy& request)
-> clap::ext::gui::plugin::Destroy::Response { -> clap::ext::gui::plugin::Destroy::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui, gui = instance.extensions.gui,
&editor = instance.editor]() { &editor = instance.editor]() {
gui->destroy(plugin); gui->destroy(plugin);
// Cleanup is handled through RAII // Cleanup is handled through RAII
editor.reset(); editor.reset();
return Ack{}; return Ack{};
}) });
.get();
}, },
[&](clap::ext::gui::plugin::SetScale& request) [&](clap::ext::gui::plugin::SetScale& request)
-> clap::ext::gui::plugin::SetScale::Response { -> clap::ext::gui::plugin::SetScale::Response {
@@ -526,10 +525,14 @@ void ClapBridge::run() {
-> clap::ext::gui::plugin::SetParent::Response { -> clap::ext::gui::plugin::SetParent::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ // NOTE: This one in particular needs the mutual recursion
.run_in_context([&, plugin = instance.plugin.get(), // because Surge XT calls this function immediately when
gui = instance.extensions.gui, // inserting, and when the host opens the GUI at the same
&editor = instance.editor]() { // time this would otherwise deadlock
return do_mutual_recursion_on_gui_thread(
[&, plugin = instance.plugin.get(),
gui = instance.extensions.gui,
&editor = instance.editor]() {
Editor& editor_instance = Editor& editor_instance =
editor.emplace(main_context_, config_, editor.emplace(main_context_, config_,
generic_logger_, request.x11_window); generic_logger_, request.x11_window);
@@ -562,8 +565,7 @@ void ClapBridge::run() {
} }
return result; return result;
}) });
.get();
}, },
[&](const clap::ext::gui::plugin::Show& request) [&](const clap::ext::gui::plugin::Show& request)
-> clap::ext::gui::plugin::Show::Response { -> clap::ext::gui::plugin::Show::Response {