From ca416fdd37f809aad131b72545fa3285fd065336 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 4 Mar 2023 16:00:53 +0800 Subject: [PATCH] Clear queues on exit to ensure all user context references are gone, ref ryzom/ryzomcore#628 --- .../src/frontend_service/fe_receive_sub.cpp | 14 ++++++-- .../src/frontend_service/quic_transceiver.cpp | 33 ++++++++++++++++++- .../src/frontend_service/quic_transceiver.h | 3 ++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/ryzom/server/src/frontend_service/fe_receive_sub.cpp b/ryzom/server/src/frontend_service/fe_receive_sub.cpp index 7adf92ed3a..3623ce99f5 100644 --- a/ryzom/server/src/frontend_service/fe_receive_sub.cpp +++ b/ryzom/server/src/frontend_service/fe_receive_sub.cpp @@ -177,9 +177,17 @@ void CFeReceiveSub::release() nlassert( _ReceiveTask != NULL ); nlassert( _ReceiveThread != NULL ); - - delete m_QuicTransceiver; - m_QuicTransceiver = nullptr; + + if (m_QuicTransceiver) + { + m_QuicTransceiver->stop(); + + m_QuicTransceiver->clearQueue(&m_Queues[2]); + m_QuicTransceiver->clearQueue(&m_Queues[3]); + + delete m_QuicTransceiver; + m_QuicTransceiver = nullptr; + } _ReceiveTask->requireExit(); #ifdef NL_OS_UNIX diff --git a/ryzom/server/src/frontend_service/quic_transceiver.cpp b/ryzom/server/src/frontend_service/quic_transceiver.cpp index e4360446df..cbb5c886a6 100644 --- a/ryzom/server/src/frontend_service/quic_transceiver.cpp +++ b/ryzom/server/src/frontend_service/quic_transceiver.cpp @@ -403,6 +403,11 @@ void CQuicTransceiver::stop() m->Listener = null; nldebug("Listener closed"); } + + // Clear queue + nldebug("Clear current write queue"); + clearQueue(m->Buffer); + nldebug("Cleared"); } void CQuicTransceiver::release() @@ -645,12 +650,33 @@ void CQuicTransceiver::shutdownReceived(CQuicUserContext *user) NLMISC::CBufFIFO *CQuicTransceiver::swapWriteQueue(NLMISC::CBufFIFO *writeQueue) { - CAtomicFlagLockYield lock(m->BufferMutex); + CAtomicFlagLock lock(m->BufferMutex); CBufFIFO *previous = m->Buffer; m->Buffer = writeQueue; return previous; } +void CQuicTransceiver::clearQueue(NLMISC::CBufFIFO *queue) +{ + CAtomicFlagLockYield lock(m->BufferMutex); + while (!queue->empty()) + { + // Data, don't care + queue->pop(); + nlassert(!queue->empty()); + uint8 *buffer; + uint32 size; + // User ptr, need to decrease ref + queue->front(buffer, size); + CQuicUserContext *user; + nlassert(size == sizeof(user)); + memcpy(&user, buffer, size); + // Decrease ref count after pop + CQuicUserContextRelease releaseUser(user); + queue->pop(); + } +} + // void CQuicTransceiver::sendDatagram(CQuicUserContext *user, const uint8 *buffer, uint32 size) //{ // QUIC_BUFFER *buf = new QUIC_BUFFER(); // wow leak :) @@ -768,6 +794,11 @@ NLMISC::CBufFIFO *CQuicTransceiver::swapWriteQueue(NLMISC::CBufFIFO *writeQueue) return previous; } +void CQuicTransceiver::clearQueue(NLMISC::CBufFIFO *writeQueue) +{ + +} + bool CQuicTransceiver::sendDatagramSwap(CQuicUserContext *user, NLMISC::CBitMemStream &buffer) { return false; diff --git a/ryzom/server/src/frontend_service/quic_transceiver.h b/ryzom/server/src/frontend_service/quic_transceiver.h index a5cf1b7b66..878a8e5a9a 100644 --- a/ryzom/server/src/frontend_service/quic_transceiver.h +++ b/ryzom/server/src/frontend_service/quic_transceiver.h @@ -242,6 +242,9 @@ class CQuicTransceiver /// Set new write queue for incoming messages (thread-safe because mutexed) NLMISC::CBufFIFO *swapWriteQueue(NLMISC::CBufFIFO *writeQueue); + /// Clear a write queue safely + void clearQueue(NLMISC::CBufFIFO *writeQueue); + /// Check if still listening bool listening();