Merge pull request #1205 from ZappoMan/bugfixes

implement ReadWriteLock for VoxelTree to fix crashes in VoxelServer
This commit is contained in:
Philip Rosedale 2013-11-06 15:42:14 -08:00
commit 43daafbe51
6 changed files with 20 additions and 13 deletions

View file

@ -33,7 +33,9 @@ bool VoxelPersistThread::process() {
{
PerformanceWarning warn(true, "Loading Voxel File", true);
_tree->lockForRead();
persistantFileRead = _tree->readFromSVOFile(_filename);
_tree->unlock();
}
if (persistantFileRead) {
@ -41,7 +43,9 @@ bool VoxelPersistThread::process() {
// after done inserting all these voxels, then reaverage colors
qDebug("BEGIN Voxels Re-Averaging\n");
_tree->lockForWrite();
_tree->reaverageVoxelColors(_tree->rootNode);
_tree->unlock();
qDebug("DONE WITH Voxels Re-Averaging\n");
}
@ -70,7 +74,9 @@ bool VoxelPersistThread::process() {
// check the dirty bit and persist here...
if (_tree->isDirty()) {
qDebug("saving voxels to file %s...\n",_filename);
_tree->lockForRead();
_tree->writeToSVOFile(_filename);
_tree->unlock();
_tree->clearDirtyBit(); // tree is clean after saving
qDebug("DONE saving voxels to file...\n");
}

View file

@ -117,7 +117,7 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
/// Version of voxel distributor that sends the deepest LOD level at once
int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nodeData, bool viewFrustumChanged) {
_myServer->lockTree();
_myServer->getTree()->lockForRead();
int truePacketsSent = 0;
int trueBytesSent = 0;
@ -360,7 +360,7 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod
} // end if bag wasn't empty, and so we sent stuff...
_myServer->unlockTree();
_myServer->getTree()->unlock();
return truePacketsSent;
}

View file

@ -343,8 +343,6 @@ void VoxelServer::run() {
parsePayload();
}
pthread_mutex_init(&_treeLock, NULL);
qInstallMessageHandler(Logging::verboseMessageHandler);
const char* STATUS_PORT = "--statusPort";
@ -591,8 +589,6 @@ void VoxelServer::run() {
// tell our NodeList we're done with notifications
nodeList->removeHook(&_nodeWatcher);
pthread_mutex_destroy(&_treeLock);
}

View file

@ -48,8 +48,6 @@ public:
VoxelTree& getServerTree() { return _serverTree; }
JurisdictionMap* getJurisdiction() { return _jurisdiction; }
void lockTree() { pthread_mutex_lock(&_treeLock); }
void unlockTree() { pthread_mutex_unlock(&_treeLock); }
VoxelTree* getTree() { return &_serverTree; }
int getPacketsPerClientPerInterval() const { return _packetsPerClientPerInterval; }
@ -80,7 +78,6 @@ private:
JurisdictionSender* _jurisdictionSender;
VoxelServerPacketProcessor* _voxelServerPacketProcessor;
VoxelPersistThread* _voxelPersistThread;
pthread_mutex_t _treeLock;
EnvironmentData _environmentData[3];
NodeWatcher _nodeWatcher; // used to cleanup AGENT data when agents are killed

View file

@ -86,9 +86,9 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
delete[] vertices;
}
_myServer->lockTree();
_myServer->getTree()->lockForWrite();
_myServer->getServerTree().readCodeColorBufferToTree(voxelData, destructive);
_myServer->unlockTree();
_myServer->getTree()->unlock();
// skip to next voxel edit record in the packet
voxelData += voxelDataSize;
@ -114,9 +114,9 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
} else if (packetData[0] == PACKET_TYPE_ERASE_VOXEL) {
// Send these bits off to the VoxelTree class to process them
_myServer->lockTree();
_myServer->getTree()->lockForWrite();
_myServer->getServerTree().processRemoveVoxelBitstream((unsigned char*)packetData, packetLength);
_myServer->unlockTree();
_myServer->getTree()->unlock();
// Make sure our Node and NodeList knows we've heard from this node.
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);

View file

@ -21,6 +21,7 @@
#include "VoxelEditPacketSender.h"
#include <QObject>
#include <QReadWriteLock>
// Callback function, for recuseTreeWithOperation
typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData);
@ -185,6 +186,11 @@ public:
// reads voxels from square image with alpha as a Y-axis
bool readFromSquareARGB32Pixels(const char *filename);
bool readFromSchematicFile(const char* filename);
// VoxelTree does not currently handle its own locking, caller must use these to lock/unlock
void lockForRead() { lock.lockForRead(); }
void lockForWrite() { lock.lockForWrite(); }
void unlock() { lock.unlock(); }
unsigned long getVoxelCount();
@ -266,6 +272,8 @@ private:
static bool nudgeCheck(VoxelNode* node, void* extraData);
void nudgeLeaf(VoxelNode* node, void* extraData);
void chunkifyLeaf(VoxelNode* node);
QReadWriteLock lock;
};
float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale);