diff --git a/src/clientagent/client_participant.cpp b/src/clientagent/client_participant.cpp index 5b1bb20..5d46906 100644 --- a/src/clientagent/client_participant.cpp +++ b/src/clientagent/client_participant.cpp @@ -52,7 +52,8 @@ ClientParticipant::ClientParticipant( } ClientParticipant::~ClientParticipant() { - NetworkClient::Shutdown(); + // Call shutdown just in-case (most likely redundant.) + Shutdown(); _clientAgent->ParticipantLeft(); } @@ -61,6 +62,13 @@ ClientParticipant::~ClientParticipant() { * Manually disconnect and delete this client participant. */ void ClientParticipant::Shutdown() { + if (_disconnected) { + return; + } + + // Kill the network connection. + NetworkClient::Shutdown(); + // Stop the heartbeat timer (if we have one.) if (_heartbeatTimer) { _heartbeatTimer->stop(); diff --git a/src/messagedirector/md_participant.cpp b/src/messagedirector/md_participant.cpp index dc6b4cb..9846b4b 100644 --- a/src/messagedirector/md_participant.cpp +++ b/src/messagedirector/md_participant.cpp @@ -17,7 +17,9 @@ MDParticipant::MDParticipant(const std::shared_ptr &socket) } MDParticipant::~MDParticipant() { - NetworkClient::Shutdown(); + // Call shutdown just in-case (most likely redundant.) + Shutdown(); + MessageDirector::Instance()->ParticipantLeft(); } @@ -25,6 +27,14 @@ MDParticipant::~MDParticipant() { * Manually disconnect and delete this MD participant. */ void MDParticipant::Shutdown() { + if (_disconnected) { + return; + } + + // Kill the network connection. + NetworkClient::Shutdown(); + + // Unsubscribe from all channels so post removes aren't accidently routed to us. ChannelSubscriber::Shutdown(); Logger::Verbose(std::format("[MD] Routing {} post-remove(s) for '{}'", diff --git a/src/messagedirector/md_participant.h b/src/messagedirector/md_participant.h index 4ec0c03..dc97751 100644 --- a/src/messagedirector/md_participant.h +++ b/src/messagedirector/md_participant.h @@ -11,10 +11,10 @@ namespace Ardos { -class MDParticipant : public NetworkClient, public ChannelSubscriber { +class MDParticipant final : public NetworkClient, public ChannelSubscriber { public: explicit MDParticipant(const std::shared_ptr &socket); - ~MDParticipant(); + ~MDParticipant() override; private: void Shutdown() override; diff --git a/src/net/network_client.cpp b/src/net/network_client.cpp index ed3a223..c467cc3 100644 --- a/src/net/network_client.cpp +++ b/src/net/network_client.cpp @@ -35,9 +35,10 @@ NetworkClient::NetworkClient(const std::shared_ptr &socket) _socket->on( [this](const uvw::write_event &event, uvw::tcp_handle &) { - if (_disconnected && _socket != nullptr) { + if (_disconnected && !_socketClosed) { _socket->close(); - _socket.reset(); + + _socketClosed = true; } _isWriting = false; @@ -61,15 +62,16 @@ bool NetworkClient::Disconnected() const { return _disconnected; } uvw::socket_address NetworkClient::GetRemoteAddress() { return _remoteAddress; } void NetworkClient::Shutdown() { - if (_socket == nullptr) { + if (_disconnected) { return; } _disconnected = true; - if (!_isWriting) { + if (!_isWriting && !_socketClosed) { _socket->close(); - _socket.reset(); + + _socketClosed = true; } } @@ -79,7 +81,7 @@ void NetworkClient::HandleClose(uv_errno_t code) { return; } - _disconnected = true; + _socketClosed = true; HandleDisconnect(code); } @@ -139,14 +141,14 @@ void NetworkClient::SendDatagram(const std::shared_ptr &dg) { return; } - size_t sendSize = sizeof(uint16_t) + dg->Size(); + const size_t sendSize = sizeof(uint16_t) + dg->Size(); auto sendBuffer = std::unique_ptr(new char[sendSize]); - uint16_t dgSize = dg->Size(); + const uint16_t dgSize = dg->Size(); - auto sendPtr = &sendBuffer.get()[0]; + const auto sendPtr = &sendBuffer.get()[0]; // Datagram size tag. - memcpy(sendPtr, (char *)&dgSize, sizeof(uint16_t)); + memcpy(sendPtr, &dgSize, sizeof(uint16_t)); // Datagram data. memcpy(sendPtr + sizeof(uint16_t), dg->GetData(), dg->Size()); diff --git a/src/net/network_client.h b/src/net/network_client.h index d7a1ecb..706b6fa 100644 --- a/src/net/network_client.h +++ b/src/net/network_client.h @@ -25,6 +25,8 @@ class NetworkClient { virtual void HandleClientDatagram(const std::shared_ptr &dg) = 0; void SendDatagram(const std::shared_ptr &dg); + bool _disconnected = false; + private: void HandleClose(uv_errno_t code); void HandleData(const std::unique_ptr &data, size_t size); @@ -33,8 +35,9 @@ class NetworkClient { std::shared_ptr _socket; uvw::socket_address _remoteAddress; std::vector _data_buf; - bool _disconnected = false; + bool _isWriting = false; + bool _socketClosed = false; }; } // namespace Ardos