From ac0d83e5553c4131a8b9faefbcbd9a0e82c77f36 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Thu, 10 Dec 2020 21:40:52 +0100 Subject: [PATCH] Fix concurrency issue in plugin group shutdown --- CHANGELOG.md | 2 ++ src/wine-host/bridges/group.cpp | 3 ++- src/wine-host/bridges/group.h | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6347b4f..08de7811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ Versioning](https://semver.org/spec/v2.0.0.html). plugin to shut down. This could happen when using Kontakt in Bitwig, as Bitwig sets a limit on the amount of time a plugin may take to shut down when closing Bitwig. +- Fixed a potential crash or freeze when removing a lot of plugins from a plugin + group at exactly the same time. ## [2.1.0] - 2020-11-20 diff --git a/src/wine-host/bridges/group.cpp b/src/wine-host/bridges/group.cpp index d81788ca..164cabf8 100644 --- a/src/wine-host/bridges/group.cpp +++ b/src/wine-host/bridges/group.cpp @@ -135,8 +135,9 @@ void GroupBridge::handle_plugin_dispatch(size_t plugin_id) { // Defer actually shutting down the process to allow for fast plugin // scanning by allowing plugins to reuse the same group host process + std::lock_guard lock(shutdown_timer_mutex); shutdown_timer.expires_after(2s); - shutdown_timer.async_wait([&](const boost::system::error_code& error) { + shutdown_timer.async_wait([this](const boost::system::error_code& error) { // A previous timer gets canceled automatically when another plugin // exits if (error.failed()) { diff --git a/src/wine-host/bridges/group.h b/src/wine-host/bridges/group.h index 0313d249..6dfccee7 100644 --- a/src/wine-host/bridges/group.h +++ b/src/wine-host/bridges/group.h @@ -276,4 +276,9 @@ class GroupBridge { * @see handle_plugin_dispatch */ boost::asio::steady_timer shutdown_timer; + /** + * A mutex to prevent two threads from simultaneously modifying the shutdown + * timer when multiple plugins exit at the same time. + */ + std::mutex shutdown_timer_mutex; };