diff --git a/libraries/shared/src/Node.h b/libraries/shared/src/Node.h index 434618ae6c..3f7780d63d 100644 --- a/libraries/shared/src/Node.h +++ b/libraries/shared/src/Node.h @@ -71,6 +71,9 @@ public: void setPingMs(int pingMs) { _pingMs = pingMs; } void lock() { pthread_mutex_lock(&_mutex); } + + /// returns false if lock failed, true if you got the lock + bool trylock() { return (pthread_mutex_trylock(&_mutex) == 0); } void unlock() { pthread_mutex_unlock(&_mutex); } static void printLog(Node const&); diff --git a/libraries/voxel-server-library/src/VoxelSendThread.cpp b/libraries/voxel-server-library/src/VoxelSendThread.cpp index 7f16caa307..2be3f38fad 100644 --- a/libraries/voxel-server-library/src/VoxelSendThread.cpp +++ b/libraries/voxel-server-library/src/VoxelSendThread.cpp @@ -31,39 +31,47 @@ bool VoxelSendThread::process() { Node* node = NodeList::getInstance()->nodeWithUUID(_nodeUUID); if (node) { - node->lock(); // make sure the node list doesn't kill our node while we're using it - VoxelNodeData* nodeData = NULL; + // make sure the node list doesn't kill our node while we're using it + if (node->trylock()) { + VoxelNodeData* nodeData = NULL; - nodeData = (VoxelNodeData*) node->getLinkedData(); + nodeData = (VoxelNodeData*) node->getLinkedData(); - int packetsSent = 0; + int packetsSent = 0; - // Sometimes the node data has not yet been linked, in which case we can't really do anything - if (nodeData) { - bool viewFrustumChanged = nodeData->updateCurrentViewFrustum(); - if (_myServer->wantsDebugVoxelSending()) { - printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged)); + // Sometimes the node data has not yet been linked, in which case we can't really do anything + if (nodeData) { + bool viewFrustumChanged = nodeData->updateCurrentViewFrustum(); + if (_myServer->wantsDebugVoxelSending()) { + printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged)); + } + packetsSent = deepestLevelVoxelDistributor(node, nodeData, viewFrustumChanged); } - packetsSent = deepestLevelVoxelDistributor(node, nodeData, viewFrustumChanged); - } - node->unlock(); // we're done with this node for now. + node->unlock(); // we're done with this node for now. + } else { + qDebug("VoxelSendThread::process() failed to lock node...isStillRunning()=%s\n", + debug::valueOf(isStillRunning())); + } } } else { if (_myServer->wantsDebugVoxelSending()) { qDebug("VoxelSendThread::process() waiting for isInitialLoadComplete()\n"); } } - - // dynamically sleep until we need to fire off the next set of voxels - int elapsed = (usecTimestampNow() - start); - int usecToSleep = VOXEL_SEND_INTERVAL_USECS - elapsed; + + // Only sleep if we're still running... + if (isStillRunning()) { + // dynamically sleep until we need to fire off the next set of voxels + int elapsed = (usecTimestampNow() - start); + int usecToSleep = VOXEL_SEND_INTERVAL_USECS - elapsed; - if (usecToSleep > 0) { - usleep(usecToSleep); - } else { - if (_myServer->wantsDebugVoxelSending()) { - std::cout << "Last send took too much time, not sleeping!\n"; + if (usecToSleep > 0) { + usleep(usecToSleep); + } else { + if (_myServer->wantsDebugVoxelSending()) { + std::cout << "Last send took too much time, not sleeping!\n"; + } } }