From 8c22f37f29eb58db256976d43ed633f9083bddaa Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Thu, 21 May 2020 17:12:55 +0200 Subject: [PATCH] Actually host plugins in the group process --- src/wine-host/bridges/group.cpp | 42 +++++++++++++++++++++++++-------- src/wine-host/bridges/group.h | 2 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/wine-host/bridges/group.cpp b/src/wine-host/bridges/group.cpp index 3d573b15..5a84136c 100644 --- a/src/wine-host/bridges/group.cpp +++ b/src/wine-host/bridges/group.cpp @@ -71,20 +71,42 @@ GroupBridge::GroupBridge(boost::filesystem::path group_socket_path) stderr_redirect(io_context, STDERR_FILENO), group_socket_endpoint(group_socket_path.string()), group_socket_acceptor(io_context, group_socket_endpoint) { - // TODO: After initializing, listen for connections and spawn plugins - // the exact same way as what happens in `individual-host.cpp` - // TODO: Allow this process to exit when the last plugin exits. Make sure - // that that doesn't cause any race conditions. - // Write this process's original STDOUT and STDERR streams to the logger async_log_pipe_lines(stdout_redirect.pipe, stdout_buffer, "[STDOUT] "); async_log_pipe_lines(stderr_redirect.pipe, stderr_buffer, "[STDERR] "); } -void GroupBridge::handle_host_plugin(const PluginParameters& parameters) { - // TODO: Start the plugin - // TODO: Allow this process to exit when the last plugin exits. Make sure - // that that doesn't cause any race conditions. +void GroupBridge::handle_host_plugin(const PluginParameters parameters) { + // At this point the `active_plugins` map will already contain a copy of + // `parameters` along with this thread's handle + // The initialization process for a plugin is identical to that in + // `../individual-host.cpp` + logger.log("Received request to host '" + parameters.plugin_path + + "' using socket '" + parameters.socket_path + "'"); + try { + Vst2Bridge bridge(parameters.plugin_path, parameters.socket_path); + logger.log("Finished initializing '" + parameters.plugin_path + "'"); + + // Blocks the main thread until the plugin shuts down + bridge.handle_dispatch(); + + logger.log("" + parameters.plugin_path + "' has exited"); + } catch (const std::runtime_error& error) { + logger.log("Error while initializing '" + parameters.plugin_path + + "':"); + logger.log(error.what()); + } + + // After the plugin has exited (either after `effClose()` or because it + // failed to initialize), we'll remove this thread's plugin from the active + // plugins. If no active plugins remain, then we'll terminate + std::lock_guard lock(active_plugins_mutex); + + active_plugins.erase(parameters); + if (active_plugins.size() == 0) { + logger.log("All plugins have exited, shutting down the group process"); + io_context.stop(); + } } void GroupBridge::handle_incoming_connections() { @@ -187,7 +209,7 @@ uint32_t WINAPI handle_host_plugin_proxy(void* param) { // need to use manual memory management. auto thread_params = static_cast(param); GroupBridge* instance = thread_params->first; - PluginParameters& parameters = thread_params->second; + PluginParameters parameters = thread_params->second; delete thread_params; instance->handle_host_plugin(parameters); diff --git a/src/wine-host/bridges/group.h b/src/wine-host/bridges/group.h index fe38f580..e68a7177 100644 --- a/src/wine-host/bridges/group.h +++ b/src/wine-host/bridges/group.h @@ -136,7 +136,7 @@ class GroupBridge { * then the process will never exit on its own. This should not happen * though. */ - void handle_host_plugin(const PluginParameters& parameters); + void handle_host_plugin(const PluginParameters parameters); /** * Listen for new requests to spawn plugins within this process and handle