diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..28fc590c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Discord + about: Support and announcements for yabridge, as well as general discussion about using Windows plugins though Wine + url: https://discord.gg/pyNeweqadf diff --git a/.github/ISSUE_TEMPLATE/setup_help.md b/.github/ISSUE_TEMPLATE/setup_help.md index 6736d60e..faddf1ec 100644 --- a/.github/ISSUE_TEMPLATE/setup_help.md +++ b/.github/ISSUE_TEMPLATE/setup_help.md @@ -8,6 +8,8 @@ assignees: "" Thanks for giving yabridge a shot! If you're having issues with plugins not working at all or scans timing out then make sure to check out the [troubleshooting common issues](https://github.com/robbert-vdh/yabridge#troubleshooting-common-issues) section of the readme. `yabridgectl sync` will also try to diagnose most if these issues for you during setup. +Also try our [Discord](https://discord.com/invite/pyNeweqadf) for some quick help or questions. + **Problem description** A short description of the current situation. diff --git a/CHANGELOG.md b/CHANGELOG.md index 32a5a820..7f94294a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.2.1] - 2020-12-12 + +### Fixed + +- Fixed some plugins, notably the _Spitfire Audio_ plugins, from causing a + deadlock when using plugin groups in _REAPER_. Even though this did not seem + to cause any issues in other hosts, the race condition that caused this issue + could also occur elsewhere. + ## [2.2.0] - 2020-12-11 ### Added diff --git a/README.md b/README.md index a36333a1..a15bb90d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # yabridge [![Automated builds](https://github.com/robbert-vdh/yabridge/workflows/Automated%20builds/badge.svg?branch=master&event=push)](https://github.com/robbert-vdh/yabridge/actions?query=workflow%3A%22Automated+builds%22+branch%3Amaster) +[![Discord](https://img.shields.io/discord/786993304197267527.svg?label=Discord&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/pyNeweqadf) Yet Another way to use Windows VST plugins on Linux. Yabridge seamlessly supports running both 64-bit Windows VST2 plugins as well as 32-bit Windows VST2 @@ -329,6 +330,10 @@ group = "izotope" ## Troubleshooting common issues +If your problem is not listed here, then feel free to post on the [issue +tracker](https://github.com/robbert-vdh/yabridge/issues) or to ask in the +[Discord](https://discord.gg/pyNeweqadf). + - If you have the `WINEPREFIX` environment variable set and you _don't_ want all of your plugins to use that specific Wine prefix then you should unset it to allow yabridge to automatically detect Wine prefixes for you. diff --git a/meson.build b/meson.build index 01bb3857..c3b08eec 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'yabridge', 'cpp', - version : '2.2.0', + version : '2.2.1', default_options : ['warning_level=3', 'cpp_std=c++2a', 'build.cpp_std=c++2a'], ) diff --git a/src/wine-host/bridges/group.cpp b/src/wine-host/bridges/group.cpp index bbdf1f61..65f13c8b 100644 --- a/src/wine-host/bridges/group.cpp +++ b/src/wine-host/bridges/group.cpp @@ -111,17 +111,8 @@ GroupBridge::~GroupBridge() { stdio_context.stop(); } -void GroupBridge::handle_plugin_dispatch(size_t plugin_id) { - // At this point the `active_plugins` map will already contain the - // intialized plugin's `Vst2Bridge` instance and this thread's handle - HostBridge* bridge; - { - std::lock_guard lock(active_plugins_mutex); - bridge = active_plugins[plugin_id].second.get(); - } - - // Blocks this thread until the plugin shuts down, handling all events on - // the main IO context +void GroupBridge::handle_plugin_dispatch(size_t plugin_id, HostBridge* bridge) { + // Blocks this thread until the plugin shuts down bridge->run(); logger.log("'" + bridge->plugin_path.string() + "' has exited"); @@ -232,16 +223,22 @@ void GroupBridge::accept_requests() { "'"); // Start listening for dispatcher events sent to the plugin's - // socket on another thread. The actual event handling will - // still be posted to this IO context so that every plugin's - // primary event handling happens on the main thread. Since this - // is only used within this context we don't need any locks. + // socket on another thread. Parts of the actual event handling + // will still be posted to this IO context so that any events + // that potentially interact with the Win32 message loop are + // handled from the main thread. We also pass a raw pointer to + // the plugin so we don't have to immediately look the instance + // up in the map again, as this would require us to immediately + // lock the map again. This could otherwise result in a deadlock + // when using the Spitfire plugins, as they will block the + // message loop until `effOpen()` has been called and thus + // prevent this lock from happening. const size_t plugin_id = next_plugin_id.fetch_add(1); - active_plugins[plugin_id] = - std::pair(Win32Thread([this, plugin_id]() { - handle_plugin_dispatch(plugin_id); - }), - std::move(bridge)); + active_plugins[plugin_id] = std::pair( + Win32Thread([this, plugin_id, plugin_ptr = bridge.get()]() { + handle_plugin_dispatch(plugin_id, plugin_ptr); + }), + std::move(bridge)); } catch (const std::runtime_error& error) { logger.log("Error while initializing '" + request.plugin_path + "':"); diff --git a/src/wine-host/bridges/group.h b/src/wine-host/bridges/group.h index c45bd494..f1837022 100644 --- a/src/wine-host/bridges/group.h +++ b/src/wine-host/bridges/group.h @@ -141,15 +141,14 @@ class GroupBridge { * This check is delayed by a few seconds to prevent having to constantly * restart the group process during plugin scanning. * - * @param plugin_id The ID of this plugin in the `active_plugins` map. The - * thread can fetch the plugin's `Vst2Bridge` instance from that map using - * this identifier. + * @param plugin_id The ID of this plugin in the `active_plugins` map. Used + * to unload the plugin and join this thread again after the plugin exits. * * @note In the case that the process starts but no plugin gets initiated, * then the process will never exit on its own. This should not happen * though. */ - void handle_plugin_dispatch(size_t plugin_id); + void handle_plugin_dispatch(size_t plugin_id, HostBridge* bridge); /** * Listen for new requests to spawn plugins within this process and handle diff --git a/tools/yabridgectl/Cargo.lock b/tools/yabridgectl/Cargo.lock index e5babb91..1e10b0a2 100644 --- a/tools/yabridgectl/Cargo.lock +++ b/tools/yabridgectl/Cargo.lock @@ -707,7 +707,7 @@ checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" [[package]] name = "yabridgectl" -version = "2.2.0" +version = "2.2.1" dependencies = [ "aho-corasick", "anyhow", diff --git a/tools/yabridgectl/Cargo.toml b/tools/yabridgectl/Cargo.toml index 7a92bf98..ecf3f506 100644 --- a/tools/yabridgectl/Cargo.toml +++ b/tools/yabridgectl/Cargo.toml @@ -2,7 +2,7 @@ name = "yabridgectl" # This version is linked to yabridge's version for clarity's sake and because # there's not a lot going on here -version = "2.2.0" +version = "2.2.1" authors = ["Robbert van der Helm "] edition = "2018" description = "Optional utility to help set up yabridge"