mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +02:00
Defer group host shutdown
This allows for a significant speedup in plugin scanning time for plugin groups, since starting Wine processes takes up pretty much the entirety of the time spent scanning plugins.
This commit is contained in:
@@ -96,13 +96,16 @@ GroupBridge::GroupBridge(boost::filesystem::path group_socket_path)
|
|||||||
stderr_redirect(io_context, STDERR_FILENO),
|
stderr_redirect(io_context, STDERR_FILENO),
|
||||||
group_socket_endpoint(group_socket_path.string()),
|
group_socket_endpoint(group_socket_path.string()),
|
||||||
group_socket_acceptor(
|
group_socket_acceptor(
|
||||||
create_acceptor_if_inactive(io_context, group_socket_endpoint)) {
|
create_acceptor_if_inactive(io_context, group_socket_endpoint)),
|
||||||
|
shutdown_timer(io_context) {
|
||||||
// Write this process's original STDOUT and STDERR streams to the logger
|
// 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(stdout_redirect.pipe, stdout_buffer, "[STDOUT] ");
|
||||||
async_log_pipe_lines(stderr_redirect.pipe, stderr_buffer, "[STDERR] ");
|
async_log_pipe_lines(stderr_redirect.pipe, stderr_buffer, "[STDERR] ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupBridge::handle_host_plugin(const GroupRequest request) {
|
void GroupBridge::handle_host_plugin(const GroupRequest request) {
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
// At this point the `active_plugins` map will already contain a copy of
|
// At this point the `active_plugins` map will already contain a copy of
|
||||||
// `parameters` along with this thread's handle
|
// `parameters` along with this thread's handle
|
||||||
// The initialization process for a plugin is identical to that in
|
// The initialization process for a plugin is identical to that in
|
||||||
@@ -124,14 +127,27 @@ void GroupBridge::handle_host_plugin(const GroupRequest request) {
|
|||||||
|
|
||||||
// After the plugin has exited (either after `effClose()` or because it
|
// After the plugin has exited (either after `effClose()` or because it
|
||||||
// failed to initialize), we'll remove this thread's plugin from the active
|
// failed to initialize), we'll remove this thread's plugin from the active
|
||||||
// plugins. If no active plugins remain, then we'll terminate
|
// plugins. If no active plugins remain, then we'll terminate this process.
|
||||||
std::lock_guard lock(active_plugins_mutex);
|
std::lock_guard lock(active_plugins_mutex);
|
||||||
|
|
||||||
active_plugins.erase(request);
|
active_plugins.erase(request);
|
||||||
if (active_plugins.size() == 0) {
|
|
||||||
logger.log("All plugins have exited, shutting down the group process");
|
// Defer shutting down the process to allow for fast plugin scanning by
|
||||||
io_context.stop();
|
// allowing plugins to reuse the same group host process
|
||||||
}
|
shutdown_timer.expires_after(2s);
|
||||||
|
shutdown_timer.async_wait([&](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");
|
||||||
|
io_context.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupBridge::handle_incoming_connections() {
|
void GroupBridge::handle_incoming_connections() {
|
||||||
|
|||||||
@@ -126,7 +126,9 @@ class GroupBridge {
|
|||||||
*
|
*
|
||||||
* Once the plugin has exited, this thread will then remove itself from the
|
* Once the plugin has exited, this thread will then remove itself from the
|
||||||
* `active_plugins` map. If this causes the vector to become empty, we will
|
* `active_plugins` map. If this causes the vector to become empty, we will
|
||||||
* terminate this process.
|
* terminate this process. This check will be delayed by a few seconds to
|
||||||
|
* prevent having to constantly restart the group process during plugin
|
||||||
|
* scanning.
|
||||||
*
|
*
|
||||||
* @param request Information about the plugin to launch, i.e. the path to
|
* @param request Information about the plugin to launch, i.e. the path to
|
||||||
* the plugin and the path of the socket endpoint that will be used for
|
* the plugin and the path of the socket endpoint that will be used for
|
||||||
@@ -216,4 +218,13 @@ class GroupBridge {
|
|||||||
* plugin is being spawned.
|
* plugin is being spawned.
|
||||||
*/
|
*/
|
||||||
std::mutex active_plugins_mutex;
|
std::mutex active_plugins_mutex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A timer to defer shutting down the process, allowing for fast plugin
|
||||||
|
* scanning without having to start a new group host process for each
|
||||||
|
* plugin.
|
||||||
|
*
|
||||||
|
* @see handle_host_plugin
|
||||||
|
*/
|
||||||
|
boost::asio::steady_timer shutdown_timer;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user