Skip to content

Commit 5abe04b

Browse files
committed
Backported fix for CORE-6468: Wire compression causes sporadic "Error reading data from the connection." errors.
1 parent f3a580a commit 5abe04b

4 files changed

Lines changed: 30 additions & 24 deletions

File tree

src/remote/inet.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ class Select
292292
#ifdef WIRE_COMPRESS_SUPPORT
293293
if (slct_zport)
294294
{
295-
if ((slct_zport->port_flags & PORT_z_data) &&
295+
if (slct_zport->port_z_data &&
296296
(slct_zport->port_state != rem_port::DISCONNECTED))
297297
{
298298
port = slct_zport;
@@ -319,7 +319,7 @@ class Select
319319
return SEL_NO_DATA;
320320

321321
#ifdef WIRE_COMPRESS_SUPPORT
322-
if (slct_port->port_flags & PORT_z_data)
322+
if (slct_port->port_z_data)
323323
return SEL_READY;
324324
#endif
325325

@@ -337,7 +337,7 @@ class Select
337337
HandleState ok(const rem_port* port)
338338
{
339339
#ifdef WIRE_COMPRESS_SUPPORT
340-
if (port->port_flags & PORT_z_data)
340+
if (port->port_z_data)
341341
return SEL_READY;
342342
#endif
343343
SOCKET n = port->port_handle;
@@ -2058,12 +2058,11 @@ static rem_port* receive( rem_port* main_port, PACKET * packet)
20582058
do {
20592059
if (!xdr_protocol(&main_port->port_receive, packet))
20602060
{
2061-
packet->p_operation = main_port->port_flags & PORT_partial_data ? op_partial : op_exit;
2062-
main_port->port_flags &= ~PORT_partial_data;
2063-
2064-
if (packet->p_operation == op_exit) {
2061+
packet->p_operation = main_port->port_partial_data ? op_partial : op_exit;
2062+
if (packet->p_operation == op_exit)
20652063
main_port->port_state = rem_port::BROKEN;
2066-
}
2064+
2065+
main_port->port_partial_data = 0;
20672066
break;
20682067
}
20692068
#ifdef DEBUG
@@ -2130,7 +2129,7 @@ static bool select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize, SSH
21302129
*length = 0;
21312130
}
21322131
#ifdef WIRE_COMPRESS_SUPPORT
2133-
if (port->port_flags & PORT_z_data)
2132+
if (port->port_z_data)
21342133
INET_select->setZDataPort(port);
21352134
#endif
21362135
return (*length) ? true : false;
@@ -2158,7 +2157,7 @@ static bool select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize, SSH
21582157
*length = 0;
21592158
}
21602159
#ifdef WIRE_COMPRESS_SUPPORT
2161-
if (port->port_flags & PORT_z_data)
2160+
if (port->port_z_data)
21622161
INET_select->setZDataPort(port);
21632162
#endif
21642163
return (*length) ? true : false;
@@ -2819,7 +2818,7 @@ static bool inet_read( XDR* xdrs)
28192818
}
28202819

28212820
SSHORT length = end - p;
2822-
port->port_flags &= ~PORT_z_data;
2821+
port->port_z_data = 0;
28232822
if (!REMOTE_inflate(port, packet_receive2, (UCHAR*)p, length, &length))
28242823
return false;
28252824
p += length;

src/remote/remote.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,13 @@ bool_t REMOTE_getbytes (XDR* xdrs, SCHAR* buff, unsigned bytecount)
744744
}
745745

746746
rem_port* port = (rem_port*) xdrs->x_public;
747-
Firebird::RefMutexGuard queGuard(*port->port_que_sync, FB_FUNCTION);
747+
Firebird::RefMutexEnsureUnlock queGuard(*port->port_que_sync, FB_FUNCTION);
748+
queGuard.enter();
748749
if (port->port_qoffset >= port->port_queue.getCount())
749750
{
750-
port->port_flags |= PORT_partial_data;
751+
queGuard.leave();
752+
753+
port->port_partial_data = 1;
751754
return FALSE;
752755
}
753756

@@ -1462,7 +1465,7 @@ bool REMOTE_inflate(rem_port* port, PacketReceive* packet_receive, UCHAR* buffer
14621465
#ifdef COMPRESS_DEBUG
14631466
fprintf(stderr, "Inflate error\n");
14641467
#endif
1465-
port->port_flags &= ~PORT_z_data;
1468+
port->port_z_data = 0;
14661469
return false;
14671470
}
14681471
#ifdef COMPRESS_DEBUG
@@ -1475,9 +1478,9 @@ bool REMOTE_inflate(rem_port* port, PacketReceive* packet_receive, UCHAR* buffer
14751478
if (strm.next_out != buffer)
14761479
break;
14771480

1478-
if (port->port_flags & PORT_z_data) // Was called from select_multi() but nothing decompressed
1481+
if (port->port_z_data) // Was called from select_multi() but nothing decompressed
14791482
{
1480-
port->port_flags &= ~PORT_z_data;
1483+
port->port_z_data = 0;
14811484
return false;
14821485
}
14831486

@@ -1494,7 +1497,7 @@ bool REMOTE_inflate(rem_port* port, PacketReceive* packet_receive, UCHAR* buffer
14941497
SSHORT l = (SSHORT) (port->port_buff_size - strm.avail_in);
14951498
if ((!packet_receive(port, strm.next_in, l, &l)) || (l <= 0)) // fixit - 2 ways to report errors in same routine
14961499
{
1497-
port->port_flags &= ~PORT_z_data;
1500+
port->port_z_data = 0;
14981501
return false;
14991502
}
15001503

@@ -1503,12 +1506,12 @@ bool REMOTE_inflate(rem_port* port, PacketReceive* packet_receive, UCHAR* buffer
15031506

15041507
*length = (SSHORT) (buffer_length - strm.avail_out);
15051508
if (strm.avail_in) // Z-buffer still has some data - probably can call inflate() once more on them
1506-
port->port_flags |= PORT_z_data;
1509+
port->port_z_data = 1;
15071510
else
1508-
port->port_flags &= ~PORT_z_data;
1511+
port->port_z_data = 0;
15091512

15101513
#ifdef COMPRESS_DEBUG
1511-
fprintf(stderr, "Z-buffer %s\n", port->port_flags & PORT_z_data ? "has data" : "is empty");
1514+
fprintf(stderr, "ZLib buffer %s\n", port->port_z_data ? "has data" : "is empty");
15121515
#endif
15131516

15141517
return true;

src/remote/remote.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -891,13 +891,13 @@ const USHORT PORT_async = 0x0002; // Port is asynchronous channel for events
891891
const USHORT PORT_no_oob = 0x0004; // Don't send out of band data
892892
const USHORT PORT_disconnect = 0x0008; // Disconnect is in progress
893893
const USHORT PORT_dummy_pckt_set= 0x0010; // A dummy packet interval is set
894-
const USHORT PORT_partial_data = 0x0020; // Physical packet doesn't contain all API packet
894+
//const USHORT PORT_partial_data = 0x0020; // Physical packet doesn't contain all API packet
895895
const USHORT PORT_lazy = 0x0040; // Deferred operations are allowed
896896
const USHORT PORT_server = 0x0080; // Server (not client) port
897897
const USHORT PORT_detached = 0x0100; // op_detach, op_drop_database or op_service_detach was processed
898898
const USHORT PORT_rdb_shutdown = 0x0200; // Database is shut down
899899
const USHORT PORT_connecting = 0x0400; // Aux connection waits for a channel to be activated by client
900-
const USHORT PORT_z_data = 0x0800; // Zlib incoming buffer has data left after decompression
900+
//const USHORT PORT_z_data = 0x0800; // Zlib incoming buffer has data left after decompression
901901
const USHORT PORT_compressed = 0x1000; // Compress outgoing stream (does not affect incoming)
902902
const USHORT PORT_released = 0x2000; // release(), complementary to the first addRef() in constructor, was called
903903

@@ -955,6 +955,9 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted
955955
USHORT port_protocol; // protocol version number
956956
USHORT port_buff_size; // port buffer size
957957
USHORT port_flags; // Misc flags
958+
Firebird::AtomicCounter
959+
port_partial_data, // Physical packet doesn't contain all API packet
960+
port_z_data; // Zlib incoming buffer has data left after decompression
958961
SLONG port_connect_timeout; // Connection timeout value
959962
SLONG port_dummy_packet_interval; // keep alive dummy packet interval
960963
SLONG port_dummy_timeout; // time remaining until keepalive packet
@@ -1031,7 +1034,8 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted
10311034
port_type(t), port_state(PENDING), port_clients(0), port_next(0),
10321035
port_parent(0), port_async(0), port_async_receive(0),
10331036
port_server(0), port_server_flags(0), port_protocol(0), port_buff_size(rpt / 2),
1034-
port_flags(0), port_connect_timeout(0), port_dummy_packet_interval(0),
1037+
port_flags(0), port_partial_data(0), port_z_data(0),
1038+
port_connect_timeout(0), port_dummy_packet_interval(0),
10351039
port_dummy_timeout(0), port_handle(INVALID_SOCKET), port_channel(INVALID_SOCKET), port_context(0),
10361040
port_events_thread(0), port_thread_guard(0),
10371041
#ifdef WIN_NT

src/remote/server/server.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2841,7 +2841,7 @@ void rem_port::disconnect(PACKET* sendL, PACKET* receiveL)
28412841
}
28422842

28432843
this->port_flags |= PORT_disconnect;
2844-
this->port_flags &= ~PORT_z_data;
2844+
this->port_z_data = 0;
28452845

28462846
if (!rdb)
28472847
{

0 commit comments

Comments
 (0)