diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index e0ff29effd..984ce42631 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -76,9 +76,9 @@ void OctreeQueryNode::deleteLater() { } -void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, const QUuid& nodeUUID) { +void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, SharedNodePointer node) { // Create octree sending thread... - _octreeSendThread = new OctreeSendThread(nodeUUID, octreeServer); + _octreeSendThread = new OctreeSendThread(octreeServer, node); _octreeSendThread->initialize(true); } diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index b7e68e805d..17d6f6337c 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -83,7 +83,7 @@ public: OctreeSceneStats stats; - void initializeOctreeSendThread(OctreeServer* octreeServer, const QUuid& nodeUUID); + void initializeOctreeSendThread(OctreeServer* octreeServer, SharedNodePointer node); bool isOctreeSendThreadInitalized() { return _octreeSendThread; } void dumpOutOfView(); diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 2fa6397ac5..382d8aa528 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -19,11 +19,10 @@ quint64 startSceneSleepTime = 0; quint64 endSceneSleepTime = 0; -OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer) : - _nodeUUID(nodeUUID), +OctreeSendThread::OctreeSendThread(OctreeServer* myServer, SharedNodePointer node) : _myServer(myServer), + _node(node), _packetData(), - _nodeMissingCount(0), _processLock(), _isShuttingDown(false) { @@ -44,7 +43,8 @@ OctreeSendThread::~OctreeSendThread() { } qDebug() << qPrintable(safeServerName) << "server [" << _myServer << "]: client disconnected " "- ending sending thread [" << this << "]"; - OctreeServer::clientDisconnected(); + _node.clear(); + OctreeServer::clientDisconnected(); } void OctreeSendThread::setIsShuttingDown() { @@ -68,35 +68,18 @@ bool OctreeSendThread::process() { return false; // exit early if we're shutting down } - const int MAX_NODE_MISSING_CHECKS = 10; - if (_nodeMissingCount > MAX_NODE_MISSING_CHECKS) { - qDebug() << "our target node:" << _nodeUUID << "has been missing the last" << _nodeMissingCount - << "times we checked, we are going to stop attempting to send."; - return false; // stop processing and shutdown, our node no longer exists - } - quint64 start = usecTimestampNow(); // don't do any send processing until the initial load of the octree is complete... if (_myServer->isInitialLoadComplete()) { - - // see if we can get access to our node, but don't wait on the lock, if the nodeList is busy - // it might not return a node that is known, but that's ok we can handle that case. - SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(_nodeUUID, false); - - if (node) { - _nodeMissingCount = 0; - OctreeQueryNode* nodeData = NULL; - - nodeData = (OctreeQueryNode*) node->getLinkedData(); + if (!_node.isNull()) { + OctreeQueryNode* nodeData = static_cast(_node->getLinkedData()); // Sometimes the node data has not yet been linked, in which case we can't really do anything if (nodeData && !nodeData->isShuttingDown()) { bool viewFrustumChanged = nodeData->updateCurrentViewFrustum(); - packetDistributor(node, nodeData, viewFrustumChanged); + packetDistributor(_node, nodeData, viewFrustumChanged); } - } else { - _nodeMissingCount++; } } diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index ab88121ee8..4e18ee9b2a 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -21,7 +21,7 @@ class OctreeSendThread : public GenericThread { Q_OBJECT public: - OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer); + OctreeSendThread(OctreeServer* myServer, SharedNodePointer node); virtual ~OctreeSendThread(); void setIsShuttingDown(); @@ -38,7 +38,7 @@ protected: virtual bool process(); private: - QUuid _nodeUUID; + SharedNodePointer _node; OctreeServer* _myServer; int handlePacketSend(const SharedNodePointer& node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent); @@ -46,7 +46,6 @@ private: OctreePacketData _packetData; - int _nodeMissingCount; QMutex _processLock; // don't allow us to have our nodeData, or our thread to be deleted while we're processing bool _isShuttingDown; }; diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index fc01b1d04a..fa087cced2 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -835,7 +835,7 @@ void OctreeServer::readPendingDatagrams() { if (debug) { qDebug() << "calling initializeOctreeSendThread()... node:" << *matchingNode; } - nodeData->initializeOctreeSendThread(this, matchingNode->getUUID()); + nodeData->initializeOctreeSendThread(this, matchingNode); } } } else if (packetType == PacketTypeJurisdictionRequest) { @@ -852,7 +852,9 @@ void OctreeServer::readPendingDatagrams() { void OctreeServer::run() { _safeServerName = getMyServerName(); + // Before we do anything else, create our tree... + OctreeElement::resetPopulationStatistics(); _tree = createTree(); // use common init to setup common timers and logging diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index cdc4f419c0..7697338a28 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -29,6 +29,11 @@ quint64 OctreeElement::_externalChildrenMemoryUsage = 0; quint64 OctreeElement::_voxelNodeCount = 0; quint64 OctreeElement::_voxelNodeLeafCount = 0; +void OctreeElement::resetPopulationStatistics() { + _voxelNodeCount = 0; + _voxelNodeLeafCount = 0; +} + OctreeElement::OctreeElement() { // Note: you must call init() from your subclass, otherwise the OctreeElement will not be properly // initialized. You will see DEADBEEF in your memory debugger if you have not properly called init() diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index ca2fa0b540..a37866bdbe 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -152,6 +152,7 @@ public: static void addUpdateHook(OctreeElementUpdateHook* hook); static void removeUpdateHook(OctreeElementUpdateHook* hook); + static void resetPopulationStatistics(); static unsigned long getNodeCount() { return _voxelNodeCount; } static unsigned long getInternalNodeCount() { return _voxelNodeCount - _voxelNodeLeafCount; } static unsigned long getLeafNodeCount() { return _voxelNodeLeafCount; } diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 6eb6eb77d8..dc5a419295 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -357,18 +357,9 @@ int NodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packet) { return 0; } -SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) { - SharedNodePointer node; - // if caller wants us to block and guarantee the correct answer, then honor that request - if (blockingLock) { - // this will block till we can get access - QMutexLocker locker(&_nodeHashMutex); - node = _nodeHash.value(nodeUUID); - } else if (_nodeHashMutex.tryLock()) { // some callers are willing to get wrong answers but not block - node = _nodeHash.value(nodeUUID); - _nodeHashMutex.unlock(); - } - return node; +SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID) { + QMutexLocker locker(&_nodeHashMutex); + return _nodeHash.value(nodeUUID); } SharedNodePointer NodeList::sendingNodeForPacket(const QByteArray& packet) { diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 0a59537a46..f10e01f3f4 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -103,8 +103,7 @@ public: QByteArray constructPingReplyPacket(const QByteArray& pingPacket); void pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& node); - /// passing false for blockingLock, will tryLock, and may return NULL when a node with the UUID actually does exist - SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true); + SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); SharedNodePointer sendingNodeForPacket(const QByteArray& packet); SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType,