Also use mutual recursion for program list changes

The VST3 version of Voxengo TEOTE would deadlock in Ardour when Ardour
calls `IEditController::setState()`, the plugin calls
`IUnitHandler::notifyProgramListChange()` in response, and then when
Ardour calls `IUnitInfo::getProgramName()` while handling that callback.
All of these functions have to be called from the same thread in Voxengo
plugins.
This commit is contained in:
Robbert van der Helm
2021-05-02 00:38:14 +02:00
parent fd29c7d825
commit 5c88140c54
3 changed files with 19 additions and 7 deletions
+2
View File
@@ -93,6 +93,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
open.
- Fixed VST3 plugins freezing in **Ardour** and **Mixbus** when the plugin tries
to automate a parameter while loading a preset.
- Fixed _Voxengo_ VST3 plugins freezing in **Ardour** and **Mixbus** when
loading a project or when duplicating the plugin instances.
- Fixed potential X11 errors resulting in assertion failures and crashes in
**Ardour** and **Mixbus** by ignoring X11 events after those hosts hides the
editor window.
@@ -175,10 +175,14 @@ tresult PLUGIN_API Vst3ComponentHandlerProxyImpl::notifyUnitSelection(
tresult PLUGIN_API Vst3ComponentHandlerProxyImpl::notifyProgramListChange(
Steinberg::Vst::ProgramListID listId,
int32 programIndex) {
return bridge.send_message(YaUnitHandler::NotifyProgramListChange{
.owner_instance_id = owner_instance_id(),
.list_id = listId,
.program_index = programIndex});
// NOTE: When a plugin calls this, Ardour will fetch the new program names
// with `IUnitInfo::getProgramName()`. TEOTE requires this to be
// called from the same thread.
return bridge.send_mutually_recursive_message(
YaUnitHandler::NotifyProgramListChange{
.owner_instance_id = owner_instance_id(),
.list_id = listId,
.program_index = programIndex});
}
tresult PLUGIN_API Vst3ComponentHandlerProxyImpl::notifyUnitByBusChange() {
+9 -3
View File
@@ -1037,10 +1037,16 @@ void Vst3Bridge::run() {
[&](const YaUnitInfo::GetProgramName& request)
-> YaUnitInfo::GetProgramName::Response {
Steinberg::Vst::String128 name{0};
// NOTE: This will likely be requested in response to
// `IUnitHandler::notifyProgramListChange`, but some
// plugins (like TEOTE) require this to be called from the
// same thread when that happens.
const tresult result =
object_instances[request.instance_id]
.unit_info->getProgramName(request.list_id,
request.program_index, name);
do_mutual_recursion_on_off_thread<tresult>([&]() {
return object_instances[request.instance_id]
.unit_info->getProgramName(
request.list_id, request.program_index, name);
});
return YaUnitInfo::GetProgramNameResponse{
.result = result, .name = tchar_pointer_to_u16string(name)};