diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.h b/assignment-client/src/octree/OctreeInboundPacketProcessor.h index 237a22d954..e2ec1b5c50 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.h +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.h @@ -44,7 +44,7 @@ typedef std::map::iterator NodeToSenderStatsMapIterato /// Handles processing of incoming network packets for the voxel-server. As with other ReceivedPacketProcessor classes /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() class OctreeInboundPacketProcessor : public ReceivedPacketProcessor { - + Q_OBJECT public: OctreeInboundPacketProcessor(OctreeServer* myServer); diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 8cb577d2f9..729b9150d0 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -35,11 +35,13 @@ OctreeQueryNode::OctreeQueryNode() : _lastClientOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE), _lodChanged(false), _lodInitialized(false), - _sequenceNumber(0) + _sequenceNumber(0), + _scheduleForDelete(false) { } OctreeQueryNode::~OctreeQueryNode() { +qDebug() << "OctreeQueryNode::~OctreeQueryNode()"; if (_octreeSendThread) { _octreeSendThread->terminate(); delete _octreeSendThread; diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 6d4dee300a..b4df18fbb8 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -23,6 +23,7 @@ class OctreeSendThread; class OctreeServer; class OctreeQueryNode : public OctreeQuery { + Q_OBJECT public: OctreeQueryNode(); virtual ~OctreeQueryNode(); @@ -85,6 +86,9 @@ public: void dumpOutOfView(); + bool isScheduledForDelete() const { return _scheduleForDelete; } + void scheduleForDelete() { _scheduleForDelete = true; } + private: OctreeQueryNode(const OctreeQueryNode &); OctreeQueryNode& operator= (const OctreeQueryNode&); @@ -119,6 +123,8 @@ private: bool _lodInitialized; OCTREE_PACKET_SEQUENCE _sequenceNumber; + + bool _scheduleForDelete; }; #endif /* defined(__hifi__OctreeQueryNode__) */ diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index ef47b4faef..98c7f2fbf5 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -34,7 +34,6 @@ OctreeSendThread::~OctreeSendThread() { bool OctreeSendThread::process() { - const int MAX_NODE_MISSING_CHECKS = 10; if (_nodeMissingCount > MAX_NODE_MISSING_CHECKS) { qDebug() << "our target node:" << _nodeUUID << "has been missing the last" << _nodeMissingCount @@ -64,6 +63,10 @@ bool OctreeSendThread::process() { } packetsSent = packetDistributor(node, nodeData, viewFrustumChanged); } + if (nodeData->isScheduledForDelete()) { + nodeData->deleteLater(); + node->setLinkedData(NULL); + } } else { _nodeMissingCount++; } @@ -83,7 +86,7 @@ bool OctreeSendThread::process() { PerformanceWarning warn(false,"OctreeSendThread... usleep()",false,&_usleepTime,&_usleepCalls); usleep(usecToSleep); } else { - if (true || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) { + if ((_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) { qDebug() << "Last send took too much time (" << (elapsed / USECS_PER_MSEC) <<" msecs), barely sleeping 1 usec!\n"; } @@ -576,13 +579,16 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue quint64 elapsedInsideUsecs = endInside - startInside; OctreeServer::trackInsideTime((float)elapsedInsideUsecs); - float insideMsecs = (float)elapsedInsideUsecs / (float)USECS_PER_MSEC; - if (insideMsecs > 1.0f) { - qDebug()<< "inside msecs=" << insideMsecs - << "lockWait usec=" << lockWaitElapsedUsec - << "encode usec=" << encodeElapsedUsec - << "compress usec=" << compressAndWriteElapsedUsec - << "sending usec=" << packetSendingElapsedUsec; + const bool wantExtraDebugging = false; + if (wantExtraDebugging) { + float insideMsecs = (float)elapsedInsideUsecs / (float)USECS_PER_MSEC; + if (insideMsecs > 1.0f) { + qDebug()<< "inside msecs=" << insideMsecs + << "lockWait usec=" << lockWaitElapsedUsec + << "encode usec=" << encodeElapsedUsec + << "compress usec=" << compressAndWriteElapsedUsec + << "sending usec=" << packetSendingElapsedUsec; + } } } @@ -607,24 +613,27 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue quint64 endCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000; int elapsedCompressTimeMsecs = endCompressTimeMsecs - startCompressTimeMsecs; - if (elapsedmsec > 100) { - if (elapsedmsec > 1000) { - int elapsedsec = (end - start)/1000000; - qDebug("WARNING! packetLoop() took %d seconds [%d milliseconds %d calls in compress] " - "to generate %d bytes in %d packets %d nodes still to send", - elapsedsec, elapsedCompressTimeMsecs, elapsedCompressCalls, - trueBytesSent, truePacketsSent, nodeData->nodeBag.count()); - } else { - qDebug("WARNING! packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] " + bool wantsExtraDebugging = false; + if (wantsExtraDebugging) { + if (elapsedmsec > 100) { + if (elapsedmsec > 1000) { + int elapsedsec = (end - start)/1000000; + qDebug("WARNING! packetLoop() took %d seconds [%d milliseconds %d calls in compress] " + "to generate %d bytes in %d packets %d nodes still to send", + elapsedsec, elapsedCompressTimeMsecs, elapsedCompressCalls, + trueBytesSent, truePacketsSent, nodeData->nodeBag.count()); + } else { + qDebug("WARNING! packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] " + "to generate %d bytes in %d packets, %d nodes still to send", + elapsedmsec, elapsedCompressTimeMsecs, elapsedCompressCalls, + trueBytesSent, truePacketsSent, nodeData->nodeBag.count()); + } + } else if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) { + qDebug("packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] " "to generate %d bytes in %d packets, %d nodes still to send", elapsedmsec, elapsedCompressTimeMsecs, elapsedCompressCalls, trueBytesSent, truePacketsSent, nodeData->nodeBag.count()); } - } else if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) { - qDebug("packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] " - "to generate %d bytes in %d packets, %d nodes still to send", - elapsedmsec, elapsedCompressTimeMsecs, elapsedCompressCalls, - trueBytesSent, truePacketsSent, nodeData->nodeBag.count()); } // if after sending packets we've emptied our bag, then we want to remember that we've sent all @@ -648,8 +657,11 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue } // end if bag wasn't empty, and so we sent stuff... - if (truePacketsSent > 0 || packetsSentThisInterval > 0) { - qDebug() << "truePacketsSent=" << truePacketsSent << "packetsSentThisInterval=" << packetsSentThisInterval; + const bool wantExtraDebugging = false; + if (wantExtraDebugging) { + if (truePacketsSent > 0 || packetsSentThisInterval > 0) { + qDebug() << "truePacketsSent=" << truePacketsSent << "packetsSentThisInterval=" << packetsSentThisInterval; + } } return truePacketsSent; diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index 081e7f411f..39c27911b0 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -19,6 +19,7 @@ /// Threaded processor for sending voxel packets to a single client class OctreeSendThread : public GenericThread { + Q_OBJECT public: OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer); virtual ~OctreeSendThread(); diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 7be8c34087..4d55455f76 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -766,12 +766,7 @@ void OctreeServer::nodeAdded(SharedNodePointer node) { void OctreeServer::nodeKilled(SharedNodePointer node) { OctreeQueryNode* nodeData = static_cast(node->getLinkedData()); if (nodeData) { - // Note: It should be safe to do this without locking the node, because if any other threads - // are using the SharedNodePointer, then they have a reference to the SharedNodePointer and the deleteLater() - // won't actually delete it until all threads have released their references to the pointer. - // But we can and should clear the linked data so that no one else tries to access it. - nodeData->deleteLater(); - node->setLinkedData(NULL); + nodeData->scheduleForDelete(); } }