mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Move the host guard handler to PluginBridge
This commit is contained in:
@@ -37,8 +37,8 @@ class PluginBridge {
|
||||
public:
|
||||
/**
|
||||
* Sets up everything needed to start the host process. Classes deriving
|
||||
* from this should call `log_init_message()` themselves after their
|
||||
* initialization list.
|
||||
* from this should call `log_init_message()` and
|
||||
* `connect_sockets_guarded()` themselves after their initialization list.
|
||||
*
|
||||
* @param plugin_type The type of the plugin we're handling.
|
||||
* @param plugin_path The path to the plugin. For VST2 plugins this is the
|
||||
@@ -197,6 +197,47 @@ class PluginBridge {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the sockets, while starting another thread that will terminate
|
||||
* the plugin (through `std::terminate`/SIGABRT) when the host process fails
|
||||
* to start. This is the only way to stop listening on our sockets without
|
||||
* moving everything over to asynchronous listeners (which may actually be a
|
||||
* good idea just for this use case). Otherwise the plugin would be stuck
|
||||
* loading indefinitely when Wine is not configured correctly.
|
||||
*
|
||||
* TODO: Asynchronously connect our sockets so we can interrupt it, maybe
|
||||
*/
|
||||
void connect_sockets_guarded() {
|
||||
#ifndef WITH_WINEDBG
|
||||
// If the Wine process fails to start, then nothing will connect to the
|
||||
// sockets and we'll be hanging here indefinitely. To prevent this,
|
||||
// we'll periodically poll whether the Wine process is still running,
|
||||
// and throw when it is not. The alternative would be to rewrite this to
|
||||
// using `async_accept`, Boost.Asio timers, and another IO context, but
|
||||
// I feel like this a much simpler solution.
|
||||
host_guard_handler = std::jthread([&](std::stop_token st) {
|
||||
using namespace std::literals::chrono_literals;
|
||||
|
||||
while (!st.stop_requested()) {
|
||||
if (!plugin_host->running()) {
|
||||
generic_logger.log(
|
||||
"The Wine host process has exited unexpectedly. Check "
|
||||
"the "
|
||||
"output above for more information.");
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
sockets.connect();
|
||||
#ifndef WITH_WINEDBG
|
||||
host_guard_handler.request_stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the plugin we're dealing with. Passed to the host process and
|
||||
* printed in the initialisation message.
|
||||
@@ -224,7 +265,10 @@ class PluginBridge {
|
||||
/**
|
||||
* The sockets used for communication with the Wine process.
|
||||
*
|
||||
* @see PluginBridge::log_init_message
|
||||
* @remark `sockets.connect()` should not be called directly.
|
||||
* `connect_sockets_guarded()` should be used instead.
|
||||
*
|
||||
* @see PluginBridge::connect_sockets_guarded
|
||||
*/
|
||||
TSockets sockets;
|
||||
|
||||
@@ -263,4 +307,14 @@ class PluginBridge {
|
||||
* STDOUT and STDERR messages.
|
||||
*/
|
||||
std::jthread wine_io_handler;
|
||||
|
||||
private:
|
||||
/**
|
||||
* A thread used during the initialisation process to terminate listening on
|
||||
* the sockets if the Wine process cannot start for whatever reason. This
|
||||
* has to be defined here instead of in the constructor we can't simply
|
||||
* detach the thread as it has to check whether the VST host is still
|
||||
* running.
|
||||
*/
|
||||
std::jthread host_guard_handler;
|
||||
};
|
||||
|
||||
@@ -61,36 +61,9 @@ Vst2PluginBridge::Vst2PluginBridge(audioMasterCallback host_callback)
|
||||
create_logger_prefix(sockets.base_dir)))) {
|
||||
log_init_message();
|
||||
|
||||
// TODO: Also move his to `PluginHost`
|
||||
#ifndef WITH_WINEDBG
|
||||
// If the Wine process fails to start, then nothing will connect to the
|
||||
// sockets and we'll be hanging here indefinitely. To prevent this, we'll
|
||||
// periodically poll whether the Wine process is still running, and throw
|
||||
// when it is not. The alternative would be to rewrite this to using
|
||||
// `async_accept`, Boost.Asio timers, and another IO context, but I feel
|
||||
// like this a much simpler solution.
|
||||
host_guard_handler = std::jthread([&](std::stop_token st) {
|
||||
using namespace std::literals::chrono_literals;
|
||||
|
||||
while (!st.stop_requested()) {
|
||||
if (!plugin_host->running()) {
|
||||
logger.log(
|
||||
"The Wine host process has exited unexpectedly. Check the "
|
||||
"output above for more information.");
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
// This will block until all sockets have been connected to by the Wine VST
|
||||
// host
|
||||
sockets.connect();
|
||||
#ifndef WITH_WINEDBG
|
||||
host_guard_handler.request_stop();
|
||||
#endif
|
||||
connect_sockets_guarded();
|
||||
|
||||
// Set up all pointers for our `AEffect` struct. We will fill this with data
|
||||
// from the VST plugin loaded in Wine at the end of this constructor.
|
||||
|
||||
@@ -148,15 +148,6 @@ class Vst2PluginBridge : PluginBridge<Vst2Sockets<std::jthread>> {
|
||||
*/
|
||||
Vst2Logger logger;
|
||||
|
||||
/**
|
||||
* A thread used during the initialisation process to terminate listening on
|
||||
* the sockets if the Wine process cannot start for whatever reason. This
|
||||
* has to be defined here instead of in the constructor we can't simply
|
||||
* detach the thread as it has to check whether the VST host is still
|
||||
* running.
|
||||
*/
|
||||
std::jthread host_guard_handler;
|
||||
|
||||
/**
|
||||
* A scratch buffer for sending and receiving data during `process`,
|
||||
* `processReplacing` and `processDoubleReplacing` calls.
|
||||
|
||||
@@ -34,5 +34,7 @@ Vst3PluginBridge::Vst3PluginBridge()
|
||||
create_logger_prefix(sockets.base_dir)))) {
|
||||
log_init_message();
|
||||
|
||||
// TODO: Call the host guard handler
|
||||
// This will block until all sockets have been connected to by the Wine VST
|
||||
// host
|
||||
connect_sockets_guarded();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user