Let group hosts shut down on their own if unused

We would never try to shut the group host down if nothing ever tried to
connect to it. This could happen when the native host gets killed after
initializing the yabridge plugin but before it gets the chance to
request the group host process to host a plugin.
This commit is contained in:
Robbert van der Helm
2021-05-01 18:38:18 +02:00
parent a91c1a3733
commit 4ff538c7e1
3 changed files with 40 additions and 19 deletions
+4
View File
@@ -81,6 +81,10 @@ Versioning](https://semver.org/spec/v2.0.0.html).
plugins. We now explicitly reparent the window to back the root window first plugins. We now explicitly reparent the window to back the root window first
before deferring the window closing. This should fix the issue, while still before deferring the window closing. This should fix the issue, while still
keeping editor closing nice and snappy. keeping editor closing nice and snappy.
- Allow plugin group host processes to shut down by themselves if it doesn't get
a request to host any plugins. This can happen when the DAW gets killed after
starting the group host process but before the native yabridge plugins
requests the group host process to host a plugin.
- Prevented latency introducing plugins VST3 from causing **Ardour** and - Prevented latency introducing plugins VST3 from causing **Ardour** and
**Mixbus** to freeze when loading the plugin. This for example prevents **Mixbus** to freeze when loading the plugin. This for example prevents
_Neural DSP Darkglass_ from freezing when used under those DAWs. _Neural DSP Darkglass_ from freezing when used under those DAWs.
+29 -19
View File
@@ -150,31 +150,17 @@ void GroupBridge::handle_plugin_run(size_t plugin_id, HostBridge* bridge) {
// Defer actually shutting down the process to allow for fast plugin // Defer actually shutting down the process to allow for fast plugin
// scanning by allowing plugins to reuse the same group host process // scanning by allowing plugins to reuse the same group host process
std::lock_guard lock(shutdown_timer_mutex); maybe_schedule_shutdown(4s);
shutdown_timer.expires_after(2s);
shutdown_timer.async_wait([this](const boost::system::error_code& error) {
// A previous timer gets canceled automatically when another plugin
// exits
if (error.failed()) {
return;
}
std::lock_guard lock(active_plugins_mutex);
if (active_plugins.size() == 0) {
logger.log(
"All plugins have exited, shutting down the group process");
// main_context.stop();
// FIXME: See the comment in `individual-host.cpp`
TerminateProcess(GetCurrentProcess(), 0);
}
});
} }
void GroupBridge::handle_incoming_connections() { void GroupBridge::handle_incoming_connections() {
accept_requests(); accept_requests();
async_handle_events(); async_handle_events();
// If we don't get a request to host a plugin within ten seconds, we'll shut
// the process down again.
maybe_schedule_shutdown(10s);
logger.log( logger.log(
"Group host is up and running, now accepting incoming connections"); "Group host is up and running, now accepting incoming connections");
main_context.run(); main_context.run();
@@ -332,6 +318,30 @@ boost::asio::local::stream_protocol::acceptor create_acceptor_if_inactive(
} }
} }
void GroupBridge::maybe_schedule_shutdown(
std::chrono::steady_clock::duration delay) {
std::lock_guard lock(shutdown_timer_mutex);
shutdown_timer.expires_after(delay);
shutdown_timer.async_wait([this](const boost::system::error_code& error) {
// A previous timer gets canceled automatically when another plugin
// exits
if (error.failed()) {
return;
}
std::lock_guard lock(active_plugins_mutex);
if (active_plugins.size() == 0) {
logger.log(
"All plugins have exited, shutting down the group process");
// main_context.stop();
// FIXME: See the comment in `individual-host.cpp`
TerminateProcess(GetCurrentProcess(), 0);
}
});
}
std::string create_logger_prefix(const fs::path& socket_path) { std::string create_logger_prefix(const fs::path& socket_path) {
// The group socket filename will be in the format // The group socket filename will be in the format
// '/tmp/yabridge-group-<group_name>-<wine_prefix_id>-<architecture>.sock', // '/tmp/yabridge-group-<group_name>-<wine_prefix_id>-<architecture>.sock',
+7
View File
@@ -187,6 +187,13 @@ class GroupBridge {
*/ */
void async_handle_events(); void async_handle_events();
/**
* After `delay` seconds, check if this group host process is (still)
* hosting any plugins. If not, then we'll terminate the process. When this
* function gets called multiple times later calls will reset the timer.
*/
void maybe_schedule_shutdown(std::chrono::steady_clock::duration delay);
/** /**
* The logging facility used for this group host process. Since we can't * The logging facility used for this group host process. Since we can't
* identify which plugin is generating (debug) output, every line will only * identify which plugin is generating (debug) output, every line will only