From be2d7718c8964af23c798a7431a7764167e5266e Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 17 Jan 2020 15:14:53 +0200 Subject: [PATCH] Fixed bug CORE-6231 : access violation on shutdown of xnet connection to local database when events have been registered --- src/remote/client/interface.cpp | 9 ++++++++- src/remote/os/win32/wnet.cpp | 15 ++++++++++++--- src/remote/os/win32/xnet.cpp | 11 +++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index 18fa388fbb..abb2ecbfda 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -7204,7 +7204,14 @@ static THREAD_ENTRY_DECLARE event_thread(THREAD_ENTRY_PARAM arg) P_OP operation = op_void; { // scope RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION); - stuff = port->receive(&packet); + try + { + stuff = port->receive(&packet); + } + catch(status_exception&) + { + // ignore + } operation = packet.p_operation; diff --git a/src/remote/os/win32/wnet.cpp b/src/remote/os/win32/wnet.cpp index b551112bd9..11c1fb939c 100644 --- a/src/remote/os/win32/wnet.cpp +++ b/src/remote/os/win32/wnet.cpp @@ -759,7 +759,11 @@ static void disconnect(rem_port* port) } wnet_ports->unRegisterPort(port); - port->release(); + + if (port->port_thread_guard && port->port_events_thread && !Thread::isCurrent(port->port_events_threadId)) + port->port_thread_guard->setWait(port->port_events_thread); + else + port->release(); } @@ -1332,7 +1336,7 @@ static bool packet_receive(rem_port* port, UCHAR* buffer, SSHORT buffer_length, if (!n) { - if (port->port_flags & PORT_detached) + if (port->port_flags & (PORT_detached | PORT_disconnect)) return false; return wnet_error(port, "ReadFile end-of-file", isc_net_read_err, dwError); @@ -1408,10 +1412,15 @@ static bool packet_send( rem_port* port, const SCHAR* buffer, SSHORT buffer_leng status = GetOverlappedResult(port->port_pipe, &ovrl, &n, TRUE); dwError = GetLastError(); } - if (!status) + if (!status && dwError != ERROR_NO_DATA) return wnet_error(port, "WriteFile", isc_net_write_err, dwError); if (n != length) + { + if (port->port_flags & (PORT_detached | PORT_disconnect)) + return false; + return wnet_error(port, "WriteFile truncated", isc_net_write_err, dwError); + } #if defined(DEBUG) && defined(WNET_trace) packet_print("send", reinterpret_cast(buffer), buffer_length); diff --git a/src/remote/os/win32/xnet.cpp b/src/remote/os/win32/xnet.cpp index 7385d0c09e..482f14a1f4 100644 --- a/src/remote/os/win32/xnet.cpp +++ b/src/remote/os/win32/xnet.cpp @@ -1068,6 +1068,14 @@ static void cleanup_port(rem_port* port) * **************************************/ + if (port->port_thread_guard && port->port_events_thread && !Thread::isCurrent(port->port_events_threadId)) + { + //port->port_thread_guard->setWait(port->port_events_thread); + + // Do not release XNET structures while event's thread working + Thread::waitForCompletion(port->port_events_thread); + } + if (port->port_xcc) { cleanup_comm(port->port_xcc); @@ -1996,6 +2004,9 @@ static bool_t xnet_read(XDR* xdrs) const DWORD wait_result = WaitForSingleObject(xcc->xcc_event_recv_channel_filled, XNET_RECV_WAIT_TIMEOUT); + if (port->port_flags & PORT_disconnect) + return FALSE; + if (wait_result == WAIT_OBJECT_0) { // Client has written some data for us (server) to read