From 4abc4adde967bb27a4d36c62c95c6a20431ba4c5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 26 Oct 2016 16:18:12 -0700 Subject: [PATCH] add a timer to check for readyRead backup --- libraries/networking/src/udt/Socket.cpp | 22 ++++++++++++++++++++++ libraries/networking/src/udt/Socket.h | 3 +++ 2 files changed, 25 insertions(+) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 7ddbd54593..43bd7dd973 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -32,6 +32,7 @@ using namespace udt; Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) : QObject(parent), _synTimer(new QTimer(this)), + _readyReadBackupTimer(new QTimer(this)), _shouldChangeSocketOptions(shouldChangeSocketOptions) { connect(&_udpSocket, &QUdpSocket::readyRead, this, &Socket::readPendingDatagrams); @@ -46,6 +47,11 @@ Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) : connect(&_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleSocketError(QAbstractSocket::SocketError))); connect(&_udpSocket, &QAbstractSocket::stateChanged, this, &Socket::handleStateChanged); + + // in order to help track down the zombie server bug, add a timer to check if we missed a readyRead + const int READY_READ_BACKUP_CHECK_MSECS = 10 * 1000; + connect(_readyReadBackupTimer, &QTimer::timeout, this, &Socket::checkForReadyReadBackup); + _readyReadBackupTimer->start(READY_READ_BACKUP_CHECK_MSECS); } void Socket::bind(const QHostAddress& address, quint16 port) { @@ -296,9 +302,25 @@ void Socket::messageFailed(Connection* connection, Packet::MessageNumber message } } +void Socket::checkForReadyReadBackup() { + if (_udpSocket.hasPendingDatagrams()) { + qCDebug(networking) << "Socket::checkForReadyReadBackup() detected blocked readyRead signal. Flushing pending datagrams."; + + // drop all of the pending datagrams on the floor + while (_udpSocket.hasPendingDatagrams()) { + _udpSocket.readDatagram(nullptr, 0); + } + } +} + void Socket::readPendingDatagrams() { int packetSizeWithHeader = -1; + while ((packetSizeWithHeader = _udpSocket.pendingDatagramSize()) != -1) { + + // we're reading a packet so re-start the readyRead backup timer + _readyReadBackupTimer->start(); + // grab a time point we can mark as the receive time of this packet auto receiveTime = p_high_resolution_clock::now(); diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index d65cb1406c..a811d78958 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -101,6 +101,7 @@ public slots: private slots: void readPendingDatagrams(); + void checkForReadyReadBackup(); void rateControlSync(); void handleSocketError(QAbstractSocket::SocketError socketError); @@ -136,6 +137,8 @@ private: int _synInterval { 10 }; // 10ms QTimer* _synTimer { nullptr }; + QTimer* _readyReadBackupTimer { nullptr }; + int _maxBandwidth { -1 }; std::unique_ptr _ccFactory { new CongestionControlFactory() };