mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 04:43:03 +01:00
Postfix for #7296: During shutdown op_disconnect may be sent to invalid handle; fixed segfault caused by too early destroyed port_context
This commit is contained in:
parent
6324d9cece
commit
017f313073
@ -1147,6 +1147,9 @@ inline static void reset(IStatus* status) throw()
|
||||
|
||||
inline static void defer_packet(rem_port* port, PACKET* packet, bool sent = false)
|
||||
{
|
||||
fb_assert(port->port_flags & PORT_lazy);
|
||||
fb_assert(port->port_deferred_packets);
|
||||
|
||||
// hvlad: passed packet often is rdb->rdb_packet and therefore can be
|
||||
// changed inside clear_queue. To not confuse caller we must preserve
|
||||
// packet content
|
||||
@ -7620,7 +7623,7 @@ static void finalize(rem_port* port)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* d i s c o n n e c t
|
||||
* f i n a l i z e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -7636,6 +7639,10 @@ static void finalize(rem_port* port)
|
||||
// Avoid async send during finalize
|
||||
RefMutexGuard guard(*port->port_write_sync, FB_FUNCTION);
|
||||
|
||||
// recheck with mutex taken
|
||||
if (port->port_flags & PORT_detached)
|
||||
return;
|
||||
|
||||
// Send a disconnect to the server so that it
|
||||
// gracefully terminates.
|
||||
|
||||
@ -7671,14 +7678,13 @@ static void finalize(rem_port* port)
|
||||
port->send(packet);
|
||||
}
|
||||
REMOTE_free_packet(port, packet);
|
||||
delete rdb;
|
||||
port->port_context = nullptr;
|
||||
}
|
||||
|
||||
// Cleanup the queue
|
||||
|
||||
delete port->port_deferred_packets;
|
||||
port->port_deferred_packets = nullptr;
|
||||
port->port_flags &= ~PORT_lazy;
|
||||
|
||||
port->port_flags |= PORT_detached;
|
||||
}
|
||||
@ -7698,6 +7704,9 @@ static void disconnect(rem_port* port, bool rmRef)
|
||||
|
||||
finalize(port);
|
||||
|
||||
Rdb* rdb = port->port_context;
|
||||
port->port_context = nullptr;
|
||||
|
||||
// Clear context reference for the associated event handler
|
||||
// to avoid SEGV during shutdown
|
||||
|
||||
@ -7712,6 +7721,7 @@ static void disconnect(rem_port* port, bool rmRef)
|
||||
|
||||
port->port_flags |= PORT_disconnect;
|
||||
port->disconnect();
|
||||
delete rdb;
|
||||
|
||||
// Remove from active ports
|
||||
|
||||
@ -9022,17 +9032,20 @@ static void send_partial_packet(rem_port* port, PACKET* packet)
|
||||
|
||||
// Send packets that were deferred
|
||||
|
||||
for (rem_que_packet* p = port->port_deferred_packets->begin();
|
||||
p < port->port_deferred_packets->end(); p++)
|
||||
if (port->port_deferred_packets)
|
||||
{
|
||||
if (!p->sent)
|
||||
for (rem_que_packet* p = port->port_deferred_packets->begin();
|
||||
p < port->port_deferred_packets->end(); p++)
|
||||
{
|
||||
if (!port->send_partial(&p->packet))
|
||||
if (!p->sent)
|
||||
{
|
||||
(Arg::Gds(isc_net_write_err) <<
|
||||
Arg::Gds(isc_random) << "send_partial_packet/send_partial").raise();
|
||||
if (!port->send_partial(&p->packet))
|
||||
{
|
||||
(Arg::Gds(isc_net_write_err) <<
|
||||
Arg::Gds(isc_random) << "send_partial_packet/send_partial").raise();
|
||||
}
|
||||
p->sent = true;
|
||||
}
|
||||
p->sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user