diff --git a/src/plugin/bridges/common.h b/src/plugin/bridges/common.h index cdac9a80..02e06558 100644 --- a/src/plugin/bridges/common.h +++ b/src/plugin/bridges/common.h @@ -105,7 +105,7 @@ class PluginBridge { io_context.run(); }) {} - virtual ~PluginBridge(){}; + virtual ~PluginBridge() noexcept {}; protected: /** diff --git a/src/plugin/bridges/vst2.cpp b/src/plugin/bridges/vst2.cpp index a599ed5e..1b044417 100644 --- a/src/plugin/bridges/vst2.cpp +++ b/src/plugin/bridges/vst2.cpp @@ -31,7 +31,7 @@ float get_parameter_proxy(AEffect*, int); * is sadly needed as a workaround to avoid using globals since we need free * function pointers to interface with the VST C API. */ -Vst2PluginBridge& get_bridge_instance(const AEffect& plugin) { +Vst2PluginBridge& get_bridge_instance(const AEffect& plugin) noexcept { return *static_cast(plugin.ptr3); } @@ -168,20 +168,26 @@ Vst2PluginBridge::Vst2PluginBridge(audioMasterCallback host_callback) update_aeffect(plugin, initialized_plugin); } -Vst2PluginBridge::~Vst2PluginBridge() { - // Drop all work make sure all sockets are closed - plugin_host->terminate(); +Vst2PluginBridge::~Vst2PluginBridge() noexcept { + try { + // Drop all work make sure all sockets are closed + plugin_host->terminate(); - // The `stop()` method will cause the IO context to just drop all of its - // outstanding work immediately - io_context.stop(); + // The `stop()` method will cause the IO context to just drop all of its + // outstanding work immediately + io_context.stop(); + } catch (const boost::system::system_error&) { + // It could be that the sockets have already been closed or that the + // process has already exited (at which point we probably won't be + // executing this, but maybe if all the stars align) + } } class DispatchDataConverter : DefaultDataConverter { public: DispatchDataConverter(std::vector& chunk_data, AEffect& plugin, - VstRect& editor_rectangle) + VstRect& editor_rectangle) noexcept : chunk(chunk_data), plugin(plugin), rect(editor_rectangle) {} EventPayload read(const int opcode, diff --git a/src/plugin/bridges/vst2.h b/src/plugin/bridges/vst2.h index 00d7b12f..db10f6e5 100644 --- a/src/plugin/bridges/vst2.h +++ b/src/plugin/bridges/vst2.h @@ -52,7 +52,7 @@ class Vst2PluginBridge : PluginBridge> { * Terminate the Wine plugin host process and drop all work when the module * gets unloaded. */ - ~Vst2PluginBridge(); + ~Vst2PluginBridge() noexcept override; // The four below functions are the handlers from the VST2 API. They are // called through proxy functions in `plugin.cpp`. diff --git a/src/plugin/bridges/vst3.cpp b/src/plugin/bridges/vst3.cpp index a809fbc2..07ebae90 100644 --- a/src/plugin/bridges/vst3.cpp +++ b/src/plugin/bridges/vst3.cpp @@ -363,10 +363,16 @@ Vst3PluginBridge::Vst3PluginBridge() }); } -Vst3PluginBridge::~Vst3PluginBridge() { - // Drop all work make sure all sockets are closed - plugin_host->terminate(); - io_context.stop(); +Vst3PluginBridge::~Vst3PluginBridge() noexcept { + try { + // Drop all work make sure all sockets are closed + plugin_host->terminate(); + io_context.stop(); + } catch (const boost::system::system_error&) { + // It could be that the sockets have already been closed or that the + // process has already exited (at which point we probably won't be + // executing this, but maybe if all the stars align) + } } Steinberg::IPluginFactory* Vst3PluginBridge::get_plugin_factory() { diff --git a/src/plugin/bridges/vst3.h b/src/plugin/bridges/vst3.h index c5d015ce..ad935ce0 100644 --- a/src/plugin/bridges/vst3.h +++ b/src/plugin/bridges/vst3.h @@ -53,13 +53,13 @@ class Vst3PluginBridge : PluginBridge> { * @throw std::runtime_error Thrown when the Wine plugin host could not be * found, or if it could not locate and load a VST3 module. */ - Vst3PluginBridge(); + explicit Vst3PluginBridge(); /** * Terminate the Wine plugin host process and drop all work when the module * gets unloaded. */ - ~Vst3PluginBridge(); + ~Vst3PluginBridge() noexcept; /** * When the host loads the module it will call `GetPluginFactory()` which diff --git a/src/plugin/host-process.cpp b/src/plugin/host-process.cpp index ae0a14e0..ca61be61 100644 --- a/src/plugin/host-process.cpp +++ b/src/plugin/host-process.cpp @@ -64,6 +64,8 @@ HostProcess::HostProcess(boost::asio::io_context& io_context, logger.async_log_pipe_lines(stderr_pipe, stderr_buffer, "[Wine STDERR] "); } +HostProcess::~HostProcess() noexcept {} + IndividualHost::IndividualHost(boost::asio::io_context& io_context, Logger& logger, const PluginInfo& plugin_info, @@ -108,7 +110,7 @@ fs::path IndividualHost::path() { return host_path; } -bool IndividualHost::running() { +bool IndividualHost::running() noexcept { return host.running(); } @@ -219,7 +221,7 @@ fs::path GroupHost::path() { return host_path; } -bool GroupHost::running() { +bool GroupHost::running() noexcept { // When we are unable to connect to a new or existing group host process, // then we'll consider the startup failed and we'll allow the initialization // process to terminate. diff --git a/src/plugin/host-process.h b/src/plugin/host-process.h index 2e8e669c..074ab859 100644 --- a/src/plugin/host-process.h +++ b/src/plugin/host-process.h @@ -40,7 +40,7 @@ */ class HostProcess { public: - virtual ~HostProcess(){}; + virtual ~HostProcess() noexcept; /** * Return the full path to the host application in use. The host application @@ -53,7 +53,7 @@ class HostProcess { * Return true if the host process is still running. Used during startup to * abort connecting to sockets if the Wine process has crashed. */ - virtual bool running() = 0; + virtual bool running() noexcept = 0; /** * Kill the process or cause the plugin that's being hosted to exit. @@ -133,7 +133,7 @@ class IndividualHost : public HostProcess { Sockets& sockets); boost::filesystem::path path() override; - bool running() override; + bool running() noexcept override; void terminate() override; private: @@ -180,7 +180,7 @@ class GroupHost : public HostProcess { std::string group_name); boost::filesystem::path path() override; - bool running() override; + bool running() noexcept override; void terminate() override; private: