diff --git a/src/chat/distantchat.cc b/src/chat/distantchat.cc index 27b2dd40e..141883fa0 100644 --- a/src/chat/distantchat.cc +++ b/src/chat/distantchat.cc @@ -254,15 +254,8 @@ void DistantChatService::receiveData( const RsGxsTunnelId& tunnel_id, unsigned c void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid) { - mGxsTunnels->closeExistingTunnel( - RsGxsTunnelId(dcpid), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID ); - - RS_STACK_MUTEX(mDistantChatMtx) ; - - std::map::iterator it = mDistantChatContacts.find(dcpid) ; - - if(it != mDistantChatContacts.end()) - mDistantChatContacts.erase(it) ; + // Same work, whether the close comes from the remote end or from us. + closeDistantChatConnexion(dcpid) ; } bool DistantChatService::initiateDistantChatConnexion( @@ -327,11 +320,34 @@ bool DistantChatService::getDistantChatStatus(const DistantChatPeerId& tunnel_id bool DistantChatService::closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) { - mGxsTunnels->closeExistingTunnel(RsGxsTunnelId(tunnel_id), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ; - - // also remove contact. Or do we wait for the notification? - - return true ; + // The contact has to go with the tunnel. Leaving it behind kept the + // conversation alive on our side: handleRecvDataItem() only drops incoming + // items for tunnels it finds no contact for, so a peer that keeps writing + // re-digs the tunnel and the chat we just left comes back. That is what + // markDistantChatAsClosed() does when the *remote* end closes, and closing + // it ourselves has to mean the same thing. + + bool tunnel_closed = mGxsTunnels->closeExistingTunnel( + RsGxsTunnelId(tunnel_id), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID ); + + bool contact_removed = false; + { + RS_STACK_MUTEX(mDistantChatMtx) ; + + auto it = mDistantChatContacts.find(tunnel_id) ; + + if(it != mDistantChatContacts.end()) + { + mDistantChatContacts.erase(it) ; + contact_removed = true ; + } + } + + // Answering true whatever happened made every client -- the chat window, + // the web UI, any JSON API caller -- report a conversation as closed when + // nothing had been closed at all, the tunnel having died on its own before. + + return tunnel_closed || contact_removed ; } uint32_t DistantChatService::getDistantChatPermissionFlags()