8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 02:03:04 +01:00

Fixed CORE-3724: Server hangs when working with events

This commit is contained in:
alexpeshkoff 2012-01-11 11:47:09 +00:00
parent e7ba9f95c8
commit 2963b49212

View File

@ -344,7 +344,8 @@ static bool_t packet_send(rem_port*, const SCHAR*, SSHORT);
static rem_port* receive(rem_port*, PACKET *);
static rem_port* select_accept(rem_port*);
static rem_port* select_port(rem_port*, SLCT *);
enum HandleState {SEL_BAD, SEL_TIMEOUT, SEL_NO_DATA, SEL_READY};
static rem_port* select_port(rem_port*, SLCT *, HandleState&);
static bool select_multi(rem_port*, UCHAR* buffer, SSHORT bufsize, SSHORT* length, rem_port*& port);
static int select_wait(rem_port*, SLCT *);
static int send_full(rem_port*, PACKET *);
@ -2465,23 +2466,29 @@ static rem_port* receive( rem_port* main_port, PACKET * packet)
/* Multi-client server multiplexes all known ports for incoming packets. */
for (;;) {
rem_port* port = select_port(main_port, &INET_select);
HandleState reason = SEL_BAD;
rem_port* port = select_port(main_port, &INET_select, reason);
if (port == main_port) {
if (port = select_accept(main_port))
return port;
continue;
}
if (port) {
if (port->port_dummy_timeout < 0) {
port->port_dummy_timeout = port->port_dummy_packet_interval;
if (port->port_flags & PORT_async ||
port->port_protocol < PROTOCOL_VERSION8)
{
continue;
}
packet->p_operation = op_dummy;
return port;
if (port && reason == SEL_TIMEOUT)
{
port->port_dummy_timeout = port->port_dummy_packet_interval;
if (port->port_flags & PORT_async ||
port->port_protocol < PROTOCOL_VERSION8)
{
continue;
}
packet->p_operation = op_dummy;
return port;
}
if (port && reason == SEL_READY)
{
/* We've got data -- lap it up and use it */
if (!xdr_protocol(&port->port_receive, packet))
@ -2537,8 +2544,9 @@ static bool select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize, SSH
for (;;)
{
port = select_port(main_port, &INET_select);
if (port == main_port)
HandleState reason = SEL_BAD;
port = select_port(main_port, &INET_select, reason);
if (port == main_port)
{
if ( (port = select_accept(main_port)) )
{
@ -2551,26 +2559,28 @@ static bool select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize, SSH
continue;
}
if (port)
{
if (port->port_dummy_timeout < 0)
{
port->port_dummy_timeout = port->port_dummy_packet_interval;
if (port->port_flags & PORT_async ||
port->port_protocol < PROTOCOL_VERSION8)
{
continue;
}
*length = 0;
return true;
}
if (port && reason == SEL_TIMEOUT)
{
port->port_dummy_timeout = port->port_dummy_packet_interval;
if (port->port_flags & PORT_async ||
port->port_protocol < PROTOCOL_VERSION8)
{
continue;
}
*length = 0;
return true;
}
if (port && reason == SEL_READY)
{
if (!packet_receive(port, buffer, bufsize, length))
{
*length = 0;
}
return (*length) ? true : false;
}
if (!select_wait(main_port, &INET_select))
{
port = NULL;
@ -2634,7 +2644,7 @@ static rem_port* select_accept( rem_port* main_port)
return 0;
}
static rem_port* select_port( rem_port* main_port, SLCT * selct)
static rem_port* select_port( rem_port* main_port, SLCT * selct, HandleState& reason)
{
/**************************************
*
@ -2669,10 +2679,12 @@ static rem_port* select_port( rem_port* main_port, SLCT * selct)
FD_CLR((SOCKET) port->port_handle, &selct->slct_fdset);
--selct->slct_count;
STOP_PORT_CRITICAL();
reason = SEL_READY;
return port;
}
else if (port->port_dummy_timeout < 0) {
STOP_PORT_CRITICAL();
reason = SEL_TIMEOUT;
return port;
}
}
@ -2690,23 +2702,28 @@ static rem_port* select_port( rem_port* main_port, SLCT * selct)
continue;
}
STOP_PORT_CRITICAL();
reason = SEL_BAD;
return port;
}
}
if (n < selct->slct_width && FD_ISSET(n, &selct->slct_fdset)) {
port->port_dummy_timeout = port->port_dummy_packet_interval;
FD_CLR(n, &selct->slct_fdset);
--selct->slct_count;
STOP_PORT_CRITICAL();
reason = SEL_READY;
return port;
}
else if (port->port_dummy_timeout < 0) {
STOP_PORT_CRITICAL();
reason = SEL_TIMEOUT;
return port;
}
}
STOP_PORT_CRITICAL();
#endif
reason = SEL_NO_DATA;
return NULL;
}