|
From: <ale...@us...> - 2012-01-16 15:01:28
|
Revision: 53864
http://firebird.svn.sourceforge.net/firebird/?rev=53864&view=rev
Author: alexpeshkoff
Date: 2012-01-16 15:01:17 +0000 (Mon, 16 Jan 2012)
Log Message:
-----------
Fixed CORE-3718: Client Library Hangs after unsuccessful connection to remote auxiliary (events) port
Modified Paths:
--------------
firebird/trunk/src/remote/inet.cpp
firebird/trunk/src/remote/protocol.cpp
firebird/trunk/src/remote/protocol.h
firebird/trunk/src/remote/remote.cpp
firebird/trunk/src/remote/remote.h
firebird/trunk/src/remote/server/server.cpp
Modified: firebird/trunk/src/remote/inet.cpp
===================================================================
--- firebird/trunk/src/remote/inet.cpp 2012-01-16 14:30:47 UTC (rev 53863)
+++ firebird/trunk/src/remote/inet.cpp 2012-01-16 15:01:17 UTC (rev 53864)
@@ -399,6 +399,7 @@
#endif
static rem_port* alloc_port(rem_port*, const USHORT = 0);
static rem_port* aux_connect(rem_port*, PACKET*);
+static void abort_aux_connection(rem_port*);
static rem_port* aux_request(rem_port*, PACKET*);
#if !defined(WIN_NT)
@@ -1296,6 +1297,7 @@
port->port_send_packet = send_full;
port->port_send_partial = send_partial;
port->port_connect = aux_connect;
+ port->port_abort_aux_connection = abort_aux_connection;
port->port_request = aux_request;
port->port_buff_size = (USHORT) INET_remote_buffer;
port->port_async_receive = inet_async_receive;
@@ -1317,6 +1319,15 @@
return port;
}
+static void abort_aux_connection(rem_port* port)
+{
+ if (port->port_flags & PORT_connecting)
+ {
+ shutdown(port->port_channel, 2);
+ SOCLOSE(port->port_channel);
+ }
+}
+
static rem_port* aux_connect(rem_port* port, PACKET* packet)
{
/**************************************
@@ -1396,8 +1407,9 @@
SOCKET n = socket(AF_INET, SOCK_STREAM, 0);
if (n == INVALID_SOCKET)
{
- inet_error(false, port, "socket", isc_net_event_connect_err, INET_ERRNO);
- return NULL;
+ int savedError = INET_ERRNO;
+ port->auxAcceptError(packet);
+ inet_error(false, port, "socket", isc_net_event_connect_err, savedError);
}
// NJK - Determine address and port to use.
@@ -1414,6 +1426,7 @@
if (status != 0)
{
int savedError = INET_ERRNO;
+ port->auxAcceptError(packet);
SOCLOSE(n);
inet_error(false, port, "socket", isc_net_event_connect_err, savedError);
}
@@ -1430,6 +1443,7 @@
{
int savedError = INET_ERRNO;
SOCLOSE(n);
+ port->auxAcceptError(packet);
inet_error(false, port, "connect", isc_net_event_connect_err, savedError);
}
@@ -1651,6 +1665,9 @@
*
**************************************/
+ if (port->port_async)
+ abort_aux_connection(port->port_async);
+
if (port->port_state != rem_port::PENDING)
return;
@@ -2127,7 +2144,7 @@
switch (result)
{
case Select::SEL_BAD:
- if (port->port_state == rem_port::BROKEN)
+ if (port->port_state == rem_port::BROKEN || port->port_flags & PORT_connecting)
continue;
return;
Modified: firebird/trunk/src/remote/protocol.cpp
===================================================================
--- firebird/trunk/src/remote/protocol.cpp 2012-01-16 14:30:47 UTC (rev 53863)
+++ firebird/trunk/src/remote/protocol.cpp 2012-01-16 15:01:17 UTC (rev 53864)
@@ -280,6 +280,7 @@
case op_disconnect:
case op_dummy:
case op_ping:
+ case op_abort_aux_connection:
return P_TRUE(xdrs, p);
case op_connect:
Modified: firebird/trunk/src/remote/protocol.h
===================================================================
--- firebird/trunk/src/remote/protocol.h 2012-01-16 14:30:47 UTC (rev 53863)
+++ firebird/trunk/src/remote/protocol.h 2012-01-16 15:01:17 UTC (rev 53864)
@@ -275,6 +275,8 @@
op_accept_data = 94, // Server accepts connection and returns some data to client
+ op_abort_aux_connection = 95, // Async operation - stop waiting for async connection to arrive
+
op_max
};
Modified: firebird/trunk/src/remote/remote.cpp
===================================================================
--- firebird/trunk/src/remote/remote.cpp 2012-01-16 14:30:47 UTC (rev 53863)
+++ firebird/trunk/src/remote/remote.cpp 2012-01-16 15:01:17 UTC (rev 53864)
@@ -656,6 +656,14 @@
return (*this->port_select_multi)(this, buffer, bufsize, length, port);
}
+void rem_port::abort_aux_connection()
+{
+ if (this->port_abort_aux_connection)
+ {
+ (*this->port_abort_aux_connection)(this);
+ }
+}
+
XDR_INT rem_port::send(PACKET* pckt)
{
return (*this->port_send_packet)(this, pckt);
@@ -676,6 +684,16 @@
return (*this->port_request)(this, pckt);
}
+void rem_port::auxAcceptError(PACKET* packet)
+{
+ if (port_protocol >= PROTOCOL_VERSION13)
+ {
+ packet->p_operation = op_abort_aux_connection;
+ // Ignore error return - we are already processing auxiliary connection error from the wire
+ send(packet);
+ }
+}
+
bool_t REMOTE_getbytes (XDR* xdrs, SCHAR* buff, u_int count)
{
/**************************************
Modified: firebird/trunk/src/remote/remote.h
===================================================================
--- firebird/trunk/src/remote/remote.h 2012-01-16 14:30:47 UTC (rev 53863)
+++ firebird/trunk/src/remote/remote.h 2012-01-16 15:01:17 UTC (rev 53864)
@@ -709,6 +709,7 @@
const USHORT PORT_server = 0x0080; // Server (not client) port
const USHORT PORT_detached = 0x0100; // op_detach, op_drop_database or op_service_detach was processed
const USHORT PORT_rdb_shutdown = 0x0200; // Database is shut down
+const USHORT PORT_connecting = 0x0400; // Aux connection waits for a channel to be activated by client
// Port itself
@@ -737,6 +738,7 @@
t_port_connect port_connect; // Establish secondary connection
rem_port* (*port_request)(rem_port*, PACKET*); // Request to establish secondary connection
bool (*port_select_multi)(rem_port*, UCHAR*, SSHORT, SSHORT*, RemPortPtr&); // get packet from active port
+ void (*port_abort_aux_connection)(rem_port*); // stop waiting for secondary connection
enum rem_port_t {
INET, // Internet (TCP/IP)
@@ -927,6 +929,7 @@
rem_port* connect(PACKET* pckt);
rem_port* request(PACKET* pckt);
bool select_multi(UCHAR* buffer, SSHORT bufsize, SSHORT* length, RemPortPtr& port);
+ void abort_aux_connection();
bool haveRecvData()
{
@@ -1022,6 +1025,7 @@
SSHORT asyncReceive(PACKET* asyncPacket, const UCHAR* buffer, SSHORT dataSize);
Firebird::string getRemoteId() const;
+ void auxAcceptError(PACKET* packet);
};
Modified: firebird/trunk/src/remote/server/server.cpp
===================================================================
--- firebird/trunk/src/remote/server/server.cpp 2012-01-16 14:30:47 UTC (rev 53863)
+++ firebird/trunk/src/remote/server/server.cpp 2012-01-16 15:01:17 UTC (rev 53864)
@@ -1754,6 +1754,7 @@
if (aux_port)
{
+ aux_port->port_flags |= PORT_connecting;
try
{
if (aux_port->connect(send))
@@ -1761,11 +1762,13 @@
}
catch (const Exception& ex)
{
+ aux_port->port_flags &= ~PORT_connecting;
iscLogException("", ex);
fb_assert(port->port_async == aux_port);
port->port_async = NULL;
aux_port->disconnect();
}
+ aux_port->port_flags &= ~PORT_connecting;
}
}
catch (const Exception& ex)
@@ -5504,6 +5507,7 @@
switch (getOperation(buffer, dataSize))
{
case op_cancel:
+ case op_abort_aux_connection:
break;
default:
return 0;
@@ -5530,6 +5534,12 @@
case op_cancel:
cancel_operation(this, asyncPacket->p_cancel_op.p_co_kind);
break;
+ case op_abort_aux_connection:
+ if (port_async && (port_async->port_flags & PORT_connecting))
+ {
+ port_async->abort_aux_connection();
+ }
+ break;
default:
return 0;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|