Merge pull request #2973 from matsukaze/master

Job #19700 BUG: Crash in NodeBounds::draw() fixed.
This commit is contained in:
Brad Hefta-Gaub 2014-06-02 22:41:02 -07:00
commit 6061330826
6 changed files with 56 additions and 4 deletions

View file

@ -3119,9 +3119,15 @@ void Application::domainChanged(const QString& domainHostname) {
_environment.resetToDefault(); _environment.resetToDefault();
// reset our node to stats and node to jurisdiction maps... since these must be changing... // reset our node to stats and node to jurisdiction maps... since these must be changing...
_voxelServerJurisdictions.lockForWrite();
_voxelServerJurisdictions.clear(); _voxelServerJurisdictions.clear();
_voxelServerJurisdictions.unlock();
_octreeServerSceneStats.clear(); _octreeServerSceneStats.clear();
_particleServerJurisdictions.lockForWrite();
_particleServerJurisdictions.clear(); _particleServerJurisdictions.clear();
_particleServerJurisdictions.unlock();
// reset the particle renderer // reset the particle renderer
_particles.clear(); _particles.clear();
@ -3160,10 +3166,12 @@ void Application::nodeKilled(SharedNodePointer node) {
if (node->getType() == NodeType::VoxelServer) { if (node->getType() == NodeType::VoxelServer) {
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
// see if this is the first we've heard of this node... // see if this is the first we've heard of this node...
_voxelServerJurisdictions.lockForRead();
if (_voxelServerJurisdictions.find(nodeUUID) != _voxelServerJurisdictions.end()) { if (_voxelServerJurisdictions.find(nodeUUID) != _voxelServerJurisdictions.end()) {
unsigned char* rootCode = _voxelServerJurisdictions[nodeUUID].getRootOctalCode(); unsigned char* rootCode = _voxelServerJurisdictions[nodeUUID].getRootOctalCode();
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
_voxelServerJurisdictions.unlock();
qDebug("voxel server going away...... v[%f, %f, %f, %f]", qDebug("voxel server going away...... v[%f, %f, %f, %f]",
rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s); rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s);
@ -3180,8 +3188,10 @@ void Application::nodeKilled(SharedNodePointer node) {
} }
// If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server // If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
_voxelServerJurisdictions.lockForWrite();
_voxelServerJurisdictions.erase(_voxelServerJurisdictions.find(nodeUUID)); _voxelServerJurisdictions.erase(_voxelServerJurisdictions.find(nodeUUID));
} }
_voxelServerJurisdictions.unlock();
// also clean up scene stats for that server // also clean up scene stats for that server
_octreeSceneStatsLock.lockForWrite(); _octreeSceneStatsLock.lockForWrite();
@ -3193,10 +3203,12 @@ void Application::nodeKilled(SharedNodePointer node) {
} else if (node->getType() == NodeType::ParticleServer) { } else if (node->getType() == NodeType::ParticleServer) {
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
// see if this is the first we've heard of this node... // see if this is the first we've heard of this node...
_particleServerJurisdictions.lockForRead();
if (_particleServerJurisdictions.find(nodeUUID) != _particleServerJurisdictions.end()) { if (_particleServerJurisdictions.find(nodeUUID) != _particleServerJurisdictions.end()) {
unsigned char* rootCode = _particleServerJurisdictions[nodeUUID].getRootOctalCode(); unsigned char* rootCode = _particleServerJurisdictions[nodeUUID].getRootOctalCode();
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
_particleServerJurisdictions.unlock();
qDebug("particle server going away...... v[%f, %f, %f, %f]", qDebug("particle server going away...... v[%f, %f, %f, %f]",
rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s); rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s);
@ -3213,8 +3225,10 @@ void Application::nodeKilled(SharedNodePointer node) {
} }
// If the particle server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server // If the particle server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
_particleServerJurisdictions.lockForWrite();
_particleServerJurisdictions.erase(_particleServerJurisdictions.find(nodeUUID)); _particleServerJurisdictions.erase(_particleServerJurisdictions.find(nodeUUID));
} }
_particleServerJurisdictions.unlock();
// also clean up scene stats for that server // also clean up scene stats for that server
_octreeSceneStatsLock.lockForWrite(); _octreeSceneStatsLock.lockForWrite();
@ -3227,10 +3241,12 @@ void Application::nodeKilled(SharedNodePointer node) {
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
// see if this is the first we've heard of this node... // see if this is the first we've heard of this node...
_modelServerJurisdictions.lockForRead();
if (_modelServerJurisdictions.find(nodeUUID) != _modelServerJurisdictions.end()) { if (_modelServerJurisdictions.find(nodeUUID) != _modelServerJurisdictions.end()) {
unsigned char* rootCode = _modelServerJurisdictions[nodeUUID].getRootOctalCode(); unsigned char* rootCode = _modelServerJurisdictions[nodeUUID].getRootOctalCode();
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
_modelServerJurisdictions.unlock();
qDebug("model server going away...... v[%f, %f, %f, %f]", qDebug("model server going away...... v[%f, %f, %f, %f]",
rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s); rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s);
@ -3247,8 +3263,10 @@ void Application::nodeKilled(SharedNodePointer node) {
} }
// If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server // If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
_modelServerJurisdictions.lockForWrite();
_modelServerJurisdictions.erase(_modelServerJurisdictions.find(nodeUUID)); _modelServerJurisdictions.erase(_modelServerJurisdictions.find(nodeUUID));
} }
_modelServerJurisdictions.unlock();
// also clean up scene stats for that server // also clean up scene stats for that server
_octreeSceneStatsLock.lockForWrite(); _octreeSceneStatsLock.lockForWrite();
@ -3318,7 +3336,10 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin
serverType = "Model"; serverType = "Model";
} }
jurisdiction->lockForRead();
if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { if (jurisdiction->find(nodeUUID) == jurisdiction->end()) {
jurisdiction->unlock();
qDebug("stats from new %s server... [%f, %f, %f, %f]", qDebug("stats from new %s server... [%f, %f, %f, %f]",
qPrintable(serverType), rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s); qPrintable(serverType), rootDetails.x, rootDetails.y, rootDetails.z, rootDetails.s);
@ -3332,6 +3353,8 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin
_voxelFades.push_back(fade); _voxelFades.push_back(fade);
_voxelFadesLock.unlock(); _voxelFadesLock.unlock();
} }
} else {
jurisdiction->unlock();
} }
// store jurisdiction details for later use // store jurisdiction details for later use
// This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it
@ -3339,7 +3362,9 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin
// details from the OctreeSceneStats to construct the JurisdictionMap // details from the OctreeSceneStats to construct the JurisdictionMap
JurisdictionMap jurisdictionMap; JurisdictionMap jurisdictionMap;
jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes()); jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes());
jurisdiction->lockForWrite();
(*jurisdiction)[nodeUUID] = jurisdictionMap; (*jurisdiction)[nodeUUID] = jurisdictionMap;
jurisdiction->unlock();
} }
return statsMessageLength; return statsMessageLength;
} }

View file

@ -70,14 +70,16 @@ void NodeBounds::draw() {
} }
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
serverJurisdictions->lockForRead();
if (serverJurisdictions->find(nodeUUID) != serverJurisdictions->end()) { if (serverJurisdictions->find(nodeUUID) != serverJurisdictions->end()) {
const JurisdictionMap& map = serverJurisdictions->value(nodeUUID); const JurisdictionMap& map = (*serverJurisdictions)[nodeUUID];
unsigned char* rootCode = map.getRootOctalCode(); unsigned char* rootCode = map.getRootOctalCode();
if (rootCode) { if (rootCode) {
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
serverJurisdictions->unlock();
glm::vec3 location(rootDetails.x, rootDetails.y, rootDetails.z); glm::vec3 location(rootDetails.x, rootDetails.y, rootDetails.z);
location *= (float)TREE_SCALE; location *= (float)TREE_SCALE;
@ -123,7 +125,11 @@ void NodeBounds::draw() {
selectedCenter = center; selectedCenter = center;
selectedScale = scaleFactor; selectedScale = scaleFactor;
} }
} else {
serverJurisdictions->unlock();
} }
} else {
serverJurisdictions->unlock();
} }
} }
@ -136,7 +142,7 @@ void NodeBounds::draw() {
float red, green, blue; float red, green, blue;
getColorForNodeType(selectedNode->getType(), red, green, blue); getColorForNodeType(selectedNode->getType(), red, green, blue);
glColor4f(red, green, blue, 0.2); glColor4f(red, green, blue, 0.2f);
glutSolidCube(1.0); glutSolidCube(1.0);
glPopMatrix(); glPopMatrix();
@ -229,7 +235,7 @@ void NodeBounds::drawOverlay() {
int mouseX = application->getMouseX(), int mouseX = application->getMouseX(),
mouseY = application->getMouseY(), mouseY = application->getMouseY(),
textWidth = widthText(TEXT_SCALE, 0, _overlayText); textWidth = widthText(TEXT_SCALE, 0, _overlayText);
glColor4f(0.4, 0.4, 0.4, 0.6); glColor4f(0.4f, 0.4f, 0.4f, 0.6f);
renderBevelCornersRect(mouseX + MOUSE_OFFSET, mouseY - TEXT_HEIGHT - PADDING, renderBevelCornersRect(mouseX + MOUSE_OFFSET, mouseY - TEXT_HEIGHT - PADDING,
textWidth + (2 * PADDING), TEXT_HEIGHT + (2 * PADDING), BACKGROUND_BEVEL); textWidth + (2 * PADDING), TEXT_HEIGHT + (2 * PADDING), BACKGROUND_BEVEL);
drawText(mouseX + MOUSE_OFFSET + PADDING, mouseY, TEXT_SCALE, ROTATION, FONT, _overlayText, TEXT_COLOR); drawText(mouseX + MOUSE_OFFSET + PADDING, mouseY, TEXT_SCALE, ROTATION, FONT, _overlayText, TEXT_COLOR);

View file

@ -281,8 +281,10 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're // lookup our nodeUUID in the jurisdiction map, if it's missing then we're
// missing at least one jurisdiction // missing at least one jurisdiction
serverJurisdictions.lockForRead();
if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) { if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) {
serverDetails << " unknown jurisdiction "; serverDetails << " unknown jurisdiction ";
serverJurisdictions.unlock();
} else { } else {
const JurisdictionMap& map = serverJurisdictions[nodeUUID]; const JurisdictionMap& map = serverJurisdictions[nodeUUID];
@ -305,6 +307,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
} else { } else {
serverDetails << " jurisdiction has no rootCode"; serverDetails << " jurisdiction has no rootCode";
} // root code } // root code
serverJurisdictions.unlock();
} // jurisdiction } // jurisdiction
// now lookup stats details for this server... // now lookup stats details for this server...

View file

@ -18,6 +18,7 @@
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QUuid> #include <QtCore/QUuid>
#include <QReadWriteLock>
#include <Node.h> #include <Node.h>
@ -82,7 +83,7 @@ private:
/// Map between node IDs and their reported JurisdictionMap. Typically used by classes that need to know which nodes are /// Map between node IDs and their reported JurisdictionMap. Typically used by classes that need to know which nodes are
/// managing which jurisdictions. /// managing which jurisdictions.
typedef QMap<QUuid, JurisdictionMap> NodeToJurisdictionMap; class NodeToJurisdictionMap : public QMap<QUuid, JurisdictionMap>, public QReadWriteLock {};
typedef QMap<QUuid, JurisdictionMap>::iterator NodeToJurisdictionMapIterator; typedef QMap<QUuid, JurisdictionMap>::iterator NodeToJurisdictionMapIterator;

View file

@ -71,9 +71,11 @@ bool OctreeEditPacketSender::serversExist() const {
if (_serverJurisdictions) { if (_serverJurisdictions) {
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're // lookup our nodeUUID in the jurisdiction map, if it's missing then we're
// missing at least one jurisdiction // missing at least one jurisdiction
_serverJurisdictions->lockForRead();
if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) { if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) {
atLeastOneJurisdictionMissing = true; atLeastOneJurisdictionMissing = true;
} }
_serverJurisdictions->unlock();
} }
hasServers = true; hasServers = true;
} }
@ -185,8 +187,10 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, ssize_t l
bool isMyJurisdiction = true; bool isMyJurisdiction = true;
// we need to get the jurisdiction for this // we need to get the jurisdiction for this
// here we need to get the "pending packet" for this server // here we need to get the "pending packet" for this server
_serverJurisdictions->lockForRead();
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID]; const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
isMyJurisdiction = (map.isMyJurisdiction(octCode, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN); isMyJurisdiction = (map.isMyJurisdiction(octCode, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN);
_serverJurisdictions->unlock();
if (isMyJurisdiction) { if (isMyJurisdiction) {
queuePacketToNode(nodeUUID, buffer, length); queuePacketToNode(nodeUUID, buffer, length);
} }
@ -236,12 +240,14 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
if (_serverJurisdictions) { if (_serverJurisdictions) {
// we need to get the jurisdiction for this // we need to get the jurisdiction for this
// here we need to get the "pending packet" for this server // here we need to get the "pending packet" for this server
_serverJurisdictions->lockForRead();
if ((*_serverJurisdictions).find(nodeUUID) != (*_serverJurisdictions).end()) { if ((*_serverJurisdictions).find(nodeUUID) != (*_serverJurisdictions).end()) {
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID]; const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
isMyJurisdiction = (map.isMyJurisdiction(codeColorBuffer, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN); isMyJurisdiction = (map.isMyJurisdiction(codeColorBuffer, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN);
} else { } else {
isMyJurisdiction = false; isMyJurisdiction = false;
} }
_serverJurisdictions->unlock();
} }
if (isMyJurisdiction) { if (isMyJurisdiction) {
EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID]; EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID];

View file

@ -45,9 +45,11 @@ void OctreeHeadlessViewer::queryOctree() {
qDebug() << "---------------"; qDebug() << "---------------";
qDebug() << "_jurisdictionListener=" << _jurisdictionListener; qDebug() << "_jurisdictionListener=" << _jurisdictionListener;
qDebug() << "Jurisdictions..."; qDebug() << "Jurisdictions...";
jurisdictions.lockForRead();
for (NodeToJurisdictionMapIterator i = jurisdictions.begin(); i != jurisdictions.end(); ++i) { for (NodeToJurisdictionMapIterator i = jurisdictions.begin(); i != jurisdictions.end(); ++i) {
qDebug() << i.key() << ": " << &i.value(); qDebug() << i.key() << ": " << &i.value();
} }
jurisdictions.unlock();
qDebug() << "---------------"; qDebug() << "---------------";
} }
@ -85,7 +87,9 @@ void OctreeHeadlessViewer::queryOctree() {
// if we haven't heard from this voxel server, go ahead and send it a query, so we // if we haven't heard from this voxel server, go ahead and send it a query, so we
// can get the jurisdiction... // can get the jurisdiction...
jurisdictions.lockForRead();
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
jurisdictions.unlock();
unknownJurisdictionServers++; unknownJurisdictionServers++;
} else { } else {
const JurisdictionMap& map = (jurisdictions)[nodeUUID]; const JurisdictionMap& map = (jurisdictions)[nodeUUID];
@ -95,6 +99,7 @@ void OctreeHeadlessViewer::queryOctree() {
if (rootCode) { if (rootCode) {
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
jurisdictions.unlock();
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE); serverBounds.scale(TREE_SCALE);
@ -103,6 +108,8 @@ void OctreeHeadlessViewer::queryOctree() {
if (serverFrustumLocation != ViewFrustum::OUTSIDE) { if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inViewServers++; inViewServers++;
} }
} else {
jurisdictions.unlock();
} }
} }
} }
@ -148,7 +155,9 @@ void OctreeHeadlessViewer::queryOctree() {
// if we haven't heard from this voxel server, go ahead and send it a query, so we // if we haven't heard from this voxel server, go ahead and send it a query, so we
// can get the jurisdiction... // can get the jurisdiction...
jurisdictions.lockForRead();
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
jurisdictions.unlock();
unknownView = true; // assume it's in view unknownView = true; // assume it's in view
if (wantExtraDebugging) { if (wantExtraDebugging) {
qDebug() << "no known jurisdiction for node " << *node << ", assume it's visible."; qDebug() << "no known jurisdiction for node " << *node << ", assume it's visible.";
@ -161,6 +170,7 @@ void OctreeHeadlessViewer::queryOctree() {
if (rootCode) { if (rootCode) {
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
jurisdictions.unlock();
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE); serverBounds.scale(TREE_SCALE);
@ -171,6 +181,7 @@ void OctreeHeadlessViewer::queryOctree() {
inView = false; inView = false;
} }
} else { } else {
jurisdictions.unlock();
if (wantExtraDebugging) { if (wantExtraDebugging) {
qDebug() << "Jurisdiction without RootCode for node " << *node << ". That's unusual!"; qDebug() << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
} }