mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Explicitely handle editor opening failures
This commit is contained in:
@@ -272,6 +272,8 @@ void passthrough_event(boost::asio::local::stream_protocol::socket& socket,
|
|||||||
// to create a Win32 window, pass that to the plugin, and
|
// to create a Win32 window, pass that to the plugin, and
|
||||||
// then write the corresponding X11 window handle to the
|
// then write the corresponding X11 window handle to the
|
||||||
// data pointer.
|
// data pointer.
|
||||||
|
// TODO: I really want to build a more obvious mechanism
|
||||||
|
// for this
|
||||||
return *reinterpret_cast<intptr_t*>(data);
|
return *reinterpret_cast<intptr_t*>(data);
|
||||||
}},
|
}},
|
||||||
event.payload);
|
event.payload);
|
||||||
|
|||||||
+58
-48
@@ -261,6 +261,57 @@ intptr_t HostBridge::dispatch(AEffect* /*plugin*/,
|
|||||||
// Some events need some extra handling
|
// Some events need some extra handling
|
||||||
// TODO: Handle GUI closing?
|
// TODO: Handle GUI closing?
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
break;
|
||||||
|
case effClose:
|
||||||
|
// TODO: Gracefully close the editor?
|
||||||
|
// TODO: Check whether the sockets and the endpoint are closed
|
||||||
|
// correctly
|
||||||
|
{
|
||||||
|
// Allow the plugin to handle its own shutdown. I've found a few
|
||||||
|
// plugins that work fine except for that they crash during
|
||||||
|
// shutdown. This shouldn't have any negative side effects since
|
||||||
|
// state has already been saved before this and all resources
|
||||||
|
// are cleaned up properly. Still not sure if this is a good way
|
||||||
|
// to handle this.
|
||||||
|
intptr_t return_value = 1;
|
||||||
|
try {
|
||||||
|
return_value = send_event(
|
||||||
|
host_vst_dispatch, dispatch_semaphore, converter,
|
||||||
|
std::pair<Logger&, bool>(logger, true), opcode, index,
|
||||||
|
value, data, option);
|
||||||
|
} catch (const boost::system::system_error& a) {
|
||||||
|
// Thrown when the socket gets closed because the VST plugin
|
||||||
|
// loaded into the Wine process crashed during shutdown
|
||||||
|
logger.log("The plugin crashed during shutdown, ignoring");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boost.Process will send SIGKILL to the Wien host for us when
|
||||||
|
// this class gets destroyed. Because the process is running a
|
||||||
|
// few threads Wine will say something about a segfault
|
||||||
|
// (probably related to `std::terminate`), but this doesn't seem
|
||||||
|
// to have any negative impact
|
||||||
|
|
||||||
|
// The `stop()` method will cause the IO context to just drop
|
||||||
|
// all of its work and immediately and not throw any exceptions
|
||||||
|
// that would have been caused by pipes and sockets being closed
|
||||||
|
io_context.stop();
|
||||||
|
|
||||||
|
// `std::thread`s are not interruptable, and since we're doing
|
||||||
|
// blocking synchronous reads there's no way to interrupt them.
|
||||||
|
// If we don't detach them then the runtime will call
|
||||||
|
// `std::terminate` for us. The workaround here is to simply
|
||||||
|
// detach the threads and then close all sockets. This will
|
||||||
|
// cause them to throw exceptions which we then catch and
|
||||||
|
// ignore. Please let me know if there's a better way to handle
|
||||||
|
// this.q
|
||||||
|
host_callback_handler.detach();
|
||||||
|
wine_io_handler.detach();
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case effEditOpen:
|
case effEditOpen:
|
||||||
// TODO: Should work as follows:
|
// TODO: Should work as follows:
|
||||||
// 1. Create a window in the Wine host using the Windows APIs
|
// 1. Create a window in the Wine host using the Windows APIs
|
||||||
@@ -268,60 +319,19 @@ intptr_t HostBridge::dispatch(AEffect* /*plugin*/,
|
|||||||
// 4. Use XEmbed to embmed the Wine window inside the parent
|
// 4. Use XEmbed to embmed the Wine window inside the parent
|
||||||
// window stored in the data void pointer
|
// window stored in the data void pointer
|
||||||
// 5. Return a handle to the X11 window
|
// 5. Return a handle to the X11 window
|
||||||
send_event(host_vst_dispatch, dispatch_semaphore, converter,
|
{
|
||||||
std::pair<Logger&, bool>(logger, true), opcode, index,
|
// The plugin will return 0 if it does not actually support
|
||||||
value, data, option);
|
// opening a window
|
||||||
|
const auto return_value =
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
case effClose:
|
|
||||||
// TODO: Gracefully close the editor?
|
|
||||||
// TODO: Check whether the sockets and the endpoint are closed
|
|
||||||
// correctly
|
|
||||||
|
|
||||||
// Allow the plugin to handle its own shutdown. I've found a few
|
|
||||||
// plugins that work fine except for that they crash during
|
|
||||||
// shutdown. This shouldn't have any negative side effects since
|
|
||||||
// state has already been saved before this and all resources are
|
|
||||||
// cleaned up properly. Still not sure if this is a good way to
|
|
||||||
// handle this.
|
|
||||||
intptr_t return_value = 1;
|
|
||||||
try {
|
|
||||||
return_value =
|
|
||||||
send_event(host_vst_dispatch, dispatch_semaphore, converter,
|
send_event(host_vst_dispatch, dispatch_semaphore, converter,
|
||||||
std::pair<Logger&, bool>(logger, true), opcode,
|
std::pair<Logger&, bool>(logger, true), opcode,
|
||||||
index, value, data, option);
|
index, value, data, option);
|
||||||
} catch (const boost::system::system_error& a) {
|
if (return_value == 0) {
|
||||||
// Thrown when the socket gets closed because the VST plugin
|
return 0;
|
||||||
// loaded into the Wine process crashed during shutdown
|
|
||||||
logger.log("The plugin crashed during shutdown, ignoring");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Boost.Process will send SIGKILL to the Wien host for us when this
|
|
||||||
// class gets destroyed. Because the process is running a few
|
|
||||||
// threads Wine will say something about a segfault (probably
|
|
||||||
// related to `std::terminate`), but this doesn't seem to have any
|
|
||||||
// negative impact
|
|
||||||
|
|
||||||
// The `stop()` method will cause the IO context to just drop all of
|
|
||||||
// its work and immediately and not throw any exceptions that would
|
|
||||||
// have been caused by pipes and sockets being closed
|
|
||||||
io_context.stop();
|
|
||||||
|
|
||||||
// `std::thread`s are not interruptable, and since we're doing
|
|
||||||
// blocking synchronous reads there's no way to interrupt them. If
|
|
||||||
// we don't detach them then the runtime will call `std::terminate`
|
|
||||||
// for us. The workaround here is to simply detach the threads and
|
|
||||||
// then close all sockets. This will cause them to throw exceptions
|
|
||||||
// which we then catch and ignore. Please let me know if there's a
|
|
||||||
// better way to handle this.q
|
|
||||||
host_callback_handler.detach();
|
|
||||||
wine_io_handler.detach();
|
|
||||||
|
|
||||||
delete this;
|
|
||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe reuse buffers here when dealing with chunk data
|
// TODO: Maybe reuse buffers here when dealing with chunk data
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ PluginBridge::PluginBridge(std::string plugin_dll_path,
|
|||||||
// the X11 window handle passed by the host
|
// the X11 window handle passed by the host
|
||||||
if (opcode == effEditOpen) {
|
if (opcode == effEditOpen) {
|
||||||
const auto handle = editor.open();
|
const auto handle = editor.open();
|
||||||
|
|
||||||
|
// The plugin will return 0 if it can not open its
|
||||||
|
// editor window (or if it does not support it, but in
|
||||||
|
// that case the DAW should be hiding the option)
|
||||||
const intptr_t return_value = plugin->dispatcher(
|
const intptr_t return_value = plugin->dispatcher(
|
||||||
plugin, opcode, index, value, handle, option);
|
plugin, opcode, index, value, handle, option);
|
||||||
if (return_value == 0) {
|
if (return_value == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user