fix octree server crashes on various shutdown corner cases

This commit is contained in:
ZappoMan 2014-03-18 17:44:53 -07:00
parent 220232312d
commit 499c4bd500
6 changed files with 51 additions and 13 deletions

View file

@ -194,21 +194,24 @@ void AssignmentClient::handleAuthenticationRequest() {
} }
void AssignmentClient::assignmentCompleted() { void AssignmentClient::assignmentCompleted() {
qDebug() << "START AssignmentClient::assignmentCompleted()... this=" << this << "_currentAssignment=" << _currentAssignment;
// reset the logging target to the the CHILD_TARGET_NAME // reset the logging target to the the CHILD_TARGET_NAME
Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
qDebug("Assignment finished or never started - waiting for new assignment."); qDebug("Assignment finished or never started - waiting for new assignment.");
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
// reset our NodeList by switching back to unassigned and clearing the list
nodeList->reset();
nodeList->setOwnerType(NodeType::Unassigned);
nodeList->resetNodeInterestSet();
// have us handle incoming NodeList datagrams again // have us handle incoming NodeList datagrams again
disconnect(&nodeList->getNodeSocket(), 0, _currentAssignment, 0); disconnect(&nodeList->getNodeSocket(), 0, _currentAssignment, 0);
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams); connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams);
qDebug() << "DONE AssignmentClient::assignmentCompleted()... this=" << this << "_currentAssignment was=" << _currentAssignment;
_currentAssignment = NULL; _currentAssignment = NULL;
// reset our NodeList by switching back to unassigned and clearing the list
nodeList->setOwnerType(NodeType::Unassigned);
nodeList->reset();
nodeList->resetNodeInterestSet();
} }

View file

@ -23,12 +23,23 @@ OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer
_packetData(), _packetData(),
_nodeMissingCount(0) _nodeMissingCount(0)
{ {
qDebug() << "client connected - starting sending thread"; QString safeServerName("Octree");
if (_myServer) {
safeServerName = _myServer->getMyServerName();
}
qDebug() << qPrintable(safeServerName) << "server [" << _myServer << "]: client connected "
"- starting sending thread [" << this << "]";
OctreeServer::clientConnected(); OctreeServer::clientConnected();
} }
OctreeSendThread::~OctreeSendThread() { OctreeSendThread::~OctreeSendThread() {
qDebug() << "client disconnected - ending sending thread"; QString safeServerName("Octree");
if (_myServer) {
safeServerName = _myServer->getMyServerName();
}
qDebug() << qPrintable(safeServerName) << "server [" << _myServer << "]: client disconnected "
"- ending sending thread [" << this << "]";
OctreeServer::clientDisconnected(); OctreeServer::clientDisconnected();
} }

View file

@ -195,9 +195,11 @@ OctreeServer::OctreeServer(const QByteArray& packet) :
{ {
_instance = this; _instance = this;
_averageLoopTime.updateAverage(0); _averageLoopTime.updateAverage(0);
qDebug() << "Octree server starting... [" << this << "]";
} }
OctreeServer::~OctreeServer() { OctreeServer::~OctreeServer() {
qDebug() << qPrintable(_safeServerName) << "server shutting down... [" << this << "]";
if (_parsedArgV) { if (_parsedArgV) {
for (int i = 0; i < _argc; i++) { for (int i = 0; i < _argc; i++) {
delete[] _parsedArgV[i]; delete[] _parsedArgV[i];
@ -222,7 +224,7 @@ OctreeServer::~OctreeServer() {
delete _jurisdiction; delete _jurisdiction;
_jurisdiction = NULL; _jurisdiction = NULL;
qDebug() << "OctreeServer::~OctreeServer()... DONE"; qDebug() << qPrintable(_safeServerName) << "server DONE shutting down... [" << this << "]";
} }
void OctreeServer::initHTTPManager(int port) { void OctreeServer::initHTTPManager(int port) {
@ -808,6 +810,7 @@ void OctreeServer::readPendingDatagrams() {
} }
void OctreeServer::run() { void OctreeServer::run() {
_safeServerName = getMyServerName();
// Before we do anything else, create our tree... // Before we do anything else, create our tree...
_tree = createTree(); _tree = createTree();
@ -863,6 +866,7 @@ void OctreeServer::run() {
connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(nodeAdded(SharedNodePointer))); connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(nodeAdded(SharedNodePointer)));
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)),SLOT(nodeKilled(SharedNodePointer))); connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)),SLOT(nodeKilled(SharedNodePointer)));
// we need to ask the DS about agents so we can ping/reply with them // we need to ask the DS about agents so we can ping/reply with them
nodeList->addNodeTypeToInterestSet(NodeType::Agent); nodeList->addNodeTypeToInterestSet(NodeType::Agent);
@ -984,13 +988,26 @@ void OctreeServer::run() {
void OctreeServer::nodeAdded(SharedNodePointer node) { void OctreeServer::nodeAdded(SharedNodePointer node) {
// we might choose to use this notifier to track clients in a pending state // we might choose to use this notifier to track clients in a pending state
qDebug() << "OctreeServer::nodeAdded() node:" << *node; qDebug() << qPrintable(_safeServerName) << "server added node:" << *node;
} }
void OctreeServer::nodeKilled(SharedNodePointer node) { void OctreeServer::nodeKilled(SharedNodePointer node) {
qDebug() << qPrintable(_safeServerName) << "server killed node:" << *node;
OctreeQueryNode* nodeData = static_cast<OctreeQueryNode*>(node->getLinkedData()); OctreeQueryNode* nodeData = static_cast<OctreeQueryNode*>(node->getLinkedData());
if (nodeData) { if (nodeData) {
nodeData->scheduleForDelete(); qDebug() << qPrintable(_safeServerName) << "server resetting Linked Data for node:" << *node;
node->setLinkedData(NULL); // set this first in case another thread comes through and tryes to acces this
qDebug() << qPrintable(_safeServerName) << "server deleting Linked Data for node:" << *node;
delete nodeData;
} }
} }
void OctreeServer::aboutToFinish() {
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
nodeKilled(node);
}
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
}

View file

@ -98,6 +98,8 @@ public:
static float getAveragePacketSendingTime() { return _averagePacketSendingTime.getAverage(); } static float getAveragePacketSendingTime() { return _averagePacketSendingTime.getAverage(); }
bool handleHTTPRequest(HTTPConnection* connection, const QString& path); bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
virtual void aboutToFinish();
public slots: public slots:
/// runs the voxel server assignment /// runs the voxel server assignment
@ -134,6 +136,7 @@ protected:
time_t _started; time_t _started;
quint64 _startedUSecs; quint64 _startedUSecs;
QString _safeServerName;
static int _clientCount; static int _clientCount;
static SimpleMovingAverage _averageLoopTime; static SimpleMovingAverage _averageLoopTime;

View file

@ -29,6 +29,7 @@ void ThreadedAssignment::setFinished(bool isFinished) {
_isFinished = isFinished; _isFinished = isFinished;
if (_isFinished) { if (_isFinished) {
aboutToFinish();
emit finished(); emit finished();
} }
} }

View file

@ -9,21 +9,24 @@
#ifndef __hifi__ThreadedAssignment__ #ifndef __hifi__ThreadedAssignment__
#define __hifi__ThreadedAssignment__ #define __hifi__ThreadedAssignment__
#include <QDebug>
#include "Assignment.h" #include "Assignment.h"
class ThreadedAssignment : public Assignment { class ThreadedAssignment : public Assignment {
Q_OBJECT Q_OBJECT
public: public:
ThreadedAssignment(const QByteArray& packet); ThreadedAssignment(const QByteArray& packet);
void setFinished(bool isFinished); void setFinished(bool isFinished);
virtual void aboutToFinish() { };
public slots: public slots:
/// threaded run of assignment /// threaded run of assignment
virtual void run() = 0; virtual void run() = 0;
virtual void deleteLater(); virtual void deleteLater();
virtual void readPendingDatagrams() = 0; virtual void readPendingDatagrams() = 0;
protected: protected:
bool readAvailableDatagram(QByteArray& destinationByteArray, HifiSockAddr& senderSockAddr); bool readAvailableDatagram(QByteArray& destinationByteArray, HifiSockAddr& senderSockAddr);