more nodelist repairs for concurrency issues

This commit is contained in:
Stephen Birarda 2014-01-23 11:11:22 -08:00
parent 04286e39e6
commit b5a72ef669
4 changed files with 37 additions and 41 deletions

View file

@ -174,6 +174,12 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
listenPort = atoi(portStr);
}
// start the nodeThread so its event loop is running
_nodeThread->start();
// make sure the node thread is given highest priority
_nodeThread->setPriority(QThread::TimeCriticalPriority);
// put the NodeList and datagram processing on the node thread
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
@ -182,12 +188,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
// connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), _datagramProcessor, SLOT(processDatagrams()));
// make sure the node thread is given highest priority
_nodeThread->setPriority(QThread::TimeCriticalPriority);
// start the nodeThread so its event loop is running
_nodeThread->start();
// put the audio processing on a separate thread
QThread* audioThread = new QThread(this);
@ -236,7 +236,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
// move the silentNodeTimer to the _nodeThread
QTimer* silentNodeTimer = new QTimer(this);
QTimer* silentNodeTimer = new QTimer();
connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));
silentNodeTimer->moveToThread(_nodeThread);
silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000);
@ -282,17 +282,35 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
Application::~Application() {
qInstallMessageHandler(NULL);
// make sure we don't call the idle timer any more
delete idleTimer;
Menu::getInstance()->saveSettings();
_rearMirrorTools->saveSettings(_settings);
_settings->sync();
// let the avatar mixer know we're out
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
// ask the datagram processing thread to quit and wait until it is done
_nodeThread->thread()->quit();
_nodeThread->thread()->wait();
_nodeThread->quit();
_nodeThread->wait();
// ask the audio thread to quit and wait until it is done
_audio.thread()->quit();
_audio.thread()->wait();
_voxelProcessor.terminate();
_voxelHideShowThread.terminate();
_voxelEditSender.terminate();
_particleEditSender.terminate();
if (_persistThread) {
_persistThread->terminate();
_persistThread->deleteLater();
_persistThread = NULL;
}
storeSizeAndPosition();
saveScripts();
@ -377,9 +395,6 @@ void Application::initializeGL() {
qDebug("Voxel parsing thread created.");
}
// call terminate before exiting
connect(this, SIGNAL(aboutToQuit()), SLOT(terminate()));
// call our timer function every second
QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(timer()));
@ -1412,28 +1427,6 @@ void Application::idle() {
}
}
void Application::terminate() {
// Close serial port
// close(serial_fd);
Menu::getInstance()->saveSettings();
_rearMirrorTools->saveSettings(_settings);
_settings->sync();
// let the avatar mixer know we're out
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
_voxelProcessor.terminate();
_voxelHideShowThread.terminate();
_voxelEditSender.terminate();
_particleEditSender.terminate();
if (_persistThread) {
_persistThread->terminate();
_persistThread->deleteLater();
_persistThread = NULL;
}
}
void Application::checkBandwidthMeterClick() {
// ... to be called upon button release

View file

@ -230,7 +230,6 @@ private slots:
void timer();
void idle();
void terminate();
void setFullscreen(bool fullscreen);
void setEnable3DTVMode(bool enable3DTVMode);

View file

@ -236,7 +236,11 @@ int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr,
node->setLastHeardMicrostamp(usecTimestampNow());
if (!senderSockAddr.isNull()) {
activateSocketFromNodeCommunication(senderSockAddr);
if (senderSockAddr == node->getPublicSocket()) {
node->activatePublicSocket();
} else if (senderSockAddr == node->getLocalSocket()) {
node->activateLocalSocket();
}
}
if (node->getActiveSocket() || senderSockAddr.isNull()) {
@ -754,7 +758,7 @@ unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataByt
}
void NodeList::pingInactiveNodes() {
foreach (const SharedNodePointer& node, _nodeHash) {
foreach (const SharedNodePointer& node, getNodeHash()) {
if (!node->getActiveSocket()) {
// we don't have an active link to this node, ping it to set that up
pingPublicAndLocalSocketsForInactiveNode(node.data());
@ -791,7 +795,7 @@ void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddre
SharedNodePointer NodeList::soloNodeOfType(char nodeType) {
if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES)) != NULL) {
foreach (const SharedNodePointer& node, _nodeHash) {
foreach (const SharedNodePointer& node, getNodeHash()) {
if (node->getType() == nodeType) {
return node;
}

View file

@ -87,7 +87,6 @@ public:
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }
void clear();
void reset();
void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest);
@ -163,6 +162,7 @@ private:
void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData);
void resetDomainData(char domainField[], const char* domainData);
void domainLookup();
void clear();
};
#endif /* defined(__hifi__NodeList__) */