mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 12:10:09 +02:00
Explicitely handle editor opening failures
This commit is contained in:
+60
-50
@@ -261,6 +261,57 @@ intptr_t HostBridge::dispatch(AEffect* /*plugin*/,
|
||||
// Some events need some extra handling
|
||||
// TODO: Handle GUI closing?
|
||||
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:
|
||||
// TODO: Should work as follows:
|
||||
// 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
|
||||
// window stored in the data void pointer
|
||||
// 5. Return a handle to the X11 window
|
||||
send_event(host_vst_dispatch, dispatch_semaphore, converter,
|
||||
std::pair<Logger&, bool>(logger, true), opcode, index,
|
||||
value, data, option);
|
||||
|
||||
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 =
|
||||
{
|
||||
// The plugin will return 0 if it does not actually support
|
||||
// opening a window
|
||||
const auto 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");
|
||||
if (return_value == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// TODO: Maybe reuse buffers here when dealing with chunk data
|
||||
|
||||
Reference in New Issue
Block a user