From e69bc22222c1c8fc1c9b36d275ed23c0c82afe32 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 22 Oct 2014 12:56:55 -0700 Subject: [PATCH] Fix for streaming crash. --- .../metavoxels/src/DatagramSequencer.cpp | 2 +- libraries/metavoxels/src/DatagramSequencer.h | 3 ++ .../metavoxels/src/MetavoxelClientManager.cpp | 40 ++++++++++++++----- .../metavoxels/src/MetavoxelClientManager.h | 7 +++- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/libraries/metavoxels/src/DatagramSequencer.cpp b/libraries/metavoxels/src/DatagramSequencer.cpp index be3d684a3d..d97ed67644 100644 --- a/libraries/metavoxels/src/DatagramSequencer.cpp +++ b/libraries/metavoxels/src/DatagramSequencer.cpp @@ -301,10 +301,10 @@ void DatagramSequencer::clearReliableChannel(QObject* object) { void DatagramSequencer::sendRecordAcknowledged(const SendRecord& record) { // stop acknowledging the recorded packets while (!_receiveRecords.isEmpty() && _receiveRecords.first().packetNumber <= record.lastReceivedPacketNumber) { + emit receiveAcknowledged(0); const ReceiveRecord& received = _receiveRecords.first(); _inputStream.persistReadMappings(received.mappings); _receivedHighPriorityMessages -= received.newHighPriorityMessages; - emit receiveAcknowledged(0); _receiveRecords.removeFirst(); } _outputStream.persistWriteMappings(record.mappings); diff --git a/libraries/metavoxels/src/DatagramSequencer.h b/libraries/metavoxels/src/DatagramSequencer.h index 9a1f5a4ae0..02fbd0f365 100644 --- a/libraries/metavoxels/src/DatagramSequencer.h +++ b/libraries/metavoxels/src/DatagramSequencer.h @@ -108,6 +108,9 @@ public: /// Returns the intput channel at the specified index, creating it if necessary. ReliableChannel* getReliableInputChannel(int index = 0); + /// Returns a reference to the stored receive mappings at the specified index. + const Bitstream::ReadMappings& getReadMappings(int index) const { return _receiveRecords.at(index).mappings; } + /// Adds stats for all reliable channels to the referenced variables. void addReliableChannelStats(int& sendProgress, int& sendTotal, int& receiveProgress, int& receiveTotal) const; diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index 09164d72c4..cc5d7ef29d 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -188,7 +188,9 @@ MetavoxelClient::MetavoxelClient(const SharedNodePointer& node, MetavoxelUpdater Endpoint(node, new PacketRecord(), new PacketRecord()), _updater(updater), _reliableDeltaChannel(NULL), - _reliableDeltaID(0) { + _reliableDeltaID(0), + _dummyInputStream(_dummyDataStream), + _dummyPacketNumber(0) { connect(_sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX), SIGNAL(receivedMessage(const QVariant&, Bitstream&)), SLOT(handleMessage(const QVariant&, Bitstream&))); @@ -234,9 +236,9 @@ PacketRecord* MetavoxelClient::getAcknowledgedReceiveRecord(int packetNumber) co if (lastAcknowledged->getPacketNumber() == packetNumber) { return lastAcknowledged; } - foreach (PacketRecord* record, _clearedReceiveRecords) { - if (record->getPacketNumber() == packetNumber) { - return record; + foreach (const ClearedReceiveRecord& record, _clearedReceiveRecords) { + if (record.first->getPacketNumber() == packetNumber) { + return record.first; } } return NULL; @@ -257,8 +259,8 @@ void MetavoxelClient::recordReceive() { } _clearedSendRecords.clear(); - foreach (PacketRecord* record, _clearedReceiveRecords) { - delete record; + foreach (const ClearedReceiveRecord& record, _clearedReceiveRecords) { + delete record.first; } _clearedReceiveRecords.clear(); } @@ -273,10 +275,16 @@ void MetavoxelClient::clearSendRecordsBefore(int index) { } void MetavoxelClient::clearReceiveRecordsBefore(int index) { + // copy the mappings on first call per packet + if (_sequencer.getIncomingPacketNumber() > _dummyPacketNumber) { + _dummyPacketNumber = _sequencer.getIncomingPacketNumber(); + _dummyInputStream.copyPersistentMappings(_sequencer.getInputStream()); + } + // move to cleared list QList::iterator end = _receiveRecords.begin() + index + 1; for (QList::const_iterator it = _receiveRecords.begin(); it != end; it++) { - _clearedReceiveRecords.append(*it); + _clearedReceiveRecords.append(ClearedReceiveRecord(*it, _sequencer.getReadMappings(index))); } _receiveRecords.erase(_receiveRecords.begin(), end); } @@ -289,7 +297,6 @@ void MetavoxelClient::writeUpdateMessage(Bitstream& out) { void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { int userType = message.userType(); if (userType == MetavoxelDeltaMessage::Type) { - PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); if (_reliableDeltaChannel) { MetavoxelData reference = _remoteData; MetavoxelLOD referenceLOD = _remoteDataLOD; @@ -299,6 +306,7 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { _reliableDeltaChannel = NULL; } else { + PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); _remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _remoteDataLOD = getLastAcknowledgedSendRecord()->getLOD()); in.reset(); @@ -319,8 +327,6 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { MetavoxelDeltaPendingMessage pending = message.value(); if (pending.id > _reliableDeltaID) { _reliableDeltaID = pending.id; - _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); - _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); PacketRecord* sendRecord = getAcknowledgedSendRecord(pending.receivedPacketNumber); if (!sendRecord) { qWarning() << "Missing send record for delta" << pending.receivedPacketNumber; @@ -334,6 +340,20 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { } _remoteDataLOD = receiveRecord->getLOD(); _remoteData = receiveRecord->getData(); + + _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); + if (receiveRecord == getLastAcknowledgedReceiveRecord()) { + _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); + + } else { + _reliableDeltaChannel->getBitstream().copyPersistentMappings(_dummyInputStream); + foreach (const ClearedReceiveRecord& record, _clearedReceiveRecords) { + _reliableDeltaChannel->getBitstream().persistReadMappings(record.second); + if (record.first == receiveRecord) { + break; + } + } + } } } else { Endpoint::handleMessage(message, in); diff --git a/libraries/metavoxels/src/MetavoxelClientManager.h b/libraries/metavoxels/src/MetavoxelClientManager.h index 0a32f2986d..adab59e0ff 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.h +++ b/libraries/metavoxels/src/MetavoxelClientManager.h @@ -145,8 +145,13 @@ protected: MetavoxelData _dataCopy; QReadWriteLock _dataCopyLock; + QDataStream _dummyDataStream; + Bitstream _dummyInputStream; + int _dummyPacketNumber; QList _clearedSendRecords; - QList _clearedReceiveRecords; + + typedef QPair ClearedReceiveRecord; + QList _clearedReceiveRecords; }; #endif // hifi_MetavoxelClientManager_h