From 2615da51da07ddf45c16f0d3602e3b7b59b0016b Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 11 Dec 2020 00:32:03 +0100 Subject: [PATCH] Fix the socket waiting fix #69 e07467697ae883816f0bf48676a7e1456615ddde changed the waiting behaviour, but this meant that there was a very slight window where all secondary requests would fail when both sides have called connect(), but the other side has not already called `receive_{events,multi,messages}` to start listening on the socket. --- src/common/communication.h | 47 +++++++++++++------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/src/common/communication.h b/src/common/communication.h index 0bab1d5d..968ac1e6 100644 --- a/src/common/communication.h +++ b/src/common/communication.h @@ -413,12 +413,8 @@ class EventHandler { */ EventHandler(boost::asio::io_context& io_context, boost::asio::local::stream_protocol::endpoint endpoint, - bool listen, - std::atomic_bool& are_sockets_connected) - : io_context(io_context), - endpoint(endpoint), - socket(io_context), - are_sockets_connected(are_sockets_connected) { + bool listen) + : io_context(io_context), endpoint(endpoint), socket(io_context) { if (listen) { boost::filesystem::create_directories( boost::filesystem::path(endpoint.path()).parent_path()); @@ -544,7 +540,7 @@ class EventHandler { // `connect()`. If we get here at any other point then it // means that the plugin side is no longer listening on the // sockets, and we should thus just exit. - if (!are_sockets_connected) { + if (!sent_first_event) { std::lock_guard lock(write_mutex); write_object(socket, event); @@ -558,6 +554,10 @@ class EventHandler { } } + // This was used to always block when sending the first message, because + // the other side may not be listening for additional connections yet + sent_first_event = true; + if (logging) { auto [logger, is_dispatch] = *logging; logger.log_event_response(is_dispatch, opcode, @@ -763,10 +763,15 @@ class EventHandler { */ std::mutex write_mutex; + private: /** - * @Sockets::are_sockets_connected + * Indicates whether or not the remove has processed an event we sent from + * this side. When a Windows VST2 plugin performs a host callback in its + * constructor, before the native plugin has had time to connect to the + * sockets, we want it to always wait for the sockets to come online, but + * this fallback behaviour should only happen during initialization. */ - std::atomic_bool& are_sockets_connected; + std::atomic_bool sent_first_event = false; }; /** @@ -806,12 +811,10 @@ class Sockets { : base_dir(endpoint_base_dir), host_vst_dispatch(io_context, (base_dir / "host_vst_dispatch.sock").string(), - listen, - are_sockets_connected), + listen), vst_host_callback(io_context, (base_dir / "vst_host_callback.sock").string(), - listen, - are_sockets_connected), + listen), host_vst_parameters(io_context, (base_dir / "host_vst_parameters.sock").string(), listen), @@ -858,17 +861,8 @@ class Sockets { host_vst_parameters.connect(); host_vst_process_replacing.connect(); host_vst_control.connect(); - - are_sockets_connected = true; } - /** - * Whether or `connect()` has been called already. When a plugin host a host - * callback during its initialization, before the sockets may have been set - * up, then we'll want to wait for the sockets to be set up. - */ - inline bool connected() { return are_sockets_connected; } - /** * The base directory for our socket endpoints. All `*_endpoint` variables * below are files within this directory. @@ -907,15 +901,6 @@ class Sockets { * the configuration (from `config`) back to the Wine host. */ SocketHandler host_vst_control; - - private: - /** - * Indicates whether we have already called `connect()` or not. When a - * Windows VST2 plugin performs a host callback in its constructor, before - * the native plugin has had time to connect to the sockets, we want it to - * always wait for the sockets to come online. - */ - std::atomic_bool are_sockets_connected = false; }; /**