mirror of
https://github.com/overte-org/overte.git
synced 2025-08-12 03:39:01 +02:00
types 0 and 1 exit cleanly, type 6 crashes
This commit is contained in:
parent
b2e99b754f
commit
d2cd4fc405
16 changed files with 211 additions and 111 deletions
|
@ -116,8 +116,11 @@ void AssignmentClient::stopAssignmentClient() {
|
|||
_statsTimerACM.stop();
|
||||
if (_currentAssignment) {
|
||||
_currentAssignment->aboutToQuit();
|
||||
// _currentAssignment->aboutToFinish();
|
||||
_currentAssignment->thread()->wait();
|
||||
QThread* currentAssignmentThread = _currentAssignment->thread();
|
||||
qDebug() << "main thread waiting on _currentAssignment->thread()" << currentAssignmentThread->objectName();
|
||||
currentAssignmentThread->quit();
|
||||
currentAssignmentThread->wait();
|
||||
qDebug() << "done waiting.";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -183,6 +183,8 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
|
||||
QThread::currentThread()->setObjectName("main thread");
|
||||
|
||||
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||
|
||||
if (numForks || minForks || maxForks) {
|
||||
AssignmentClientMonitor monitor(numForks, minForks, maxForks, requestAssignmentType, assignmentPool,
|
||||
walletUUID, assignmentServerHostname, assignmentServerPort);
|
||||
|
|
|
@ -588,6 +588,7 @@ void AudioMixer::sendStatsPacket() {
|
|||
_sumMixes = 0;
|
||||
_numStatFrames = 0;
|
||||
|
||||
|
||||
// NOTE: These stats can be too large to fit in an MTU, so we break it up into multiple packts...
|
||||
QJsonObject statsObject2;
|
||||
|
||||
|
@ -711,90 +712,78 @@ void AudioMixer::run() {
|
|||
// check the settings object to see if we have anything we can parse out
|
||||
parseSettingsObject(settingsObject);
|
||||
|
||||
_nextFrame = 0;
|
||||
_timer.start();
|
||||
int nextFrame = 0;
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
_idleTimer = new QTimer();
|
||||
connect(_idleTimer, SIGNAL(timeout()), this, SLOT(insideLoop()));
|
||||
_idleTimer->start(0);
|
||||
}
|
||||
char clientMixBuffer[MAX_PACKET_SIZE];
|
||||
|
||||
int usecToSleep = AudioConstants::NETWORK_FRAME_USECS;
|
||||
|
||||
const int TRAILING_AVERAGE_FRAMES = 100;
|
||||
int framesSinceCutoffEvent = TRAILING_AVERAGE_FRAMES;
|
||||
|
||||
|
||||
void AudioMixer::insideLoop() {
|
||||
if (_isFinished) {
|
||||
qDebug() << "AudioMixer::insideLoop stoping _idleTimer";
|
||||
_idleTimer->stop();
|
||||
delete _idleTimer;
|
||||
_idleTimer = nullptr;
|
||||
|
||||
QThread *thisThread = QThread::currentThread();
|
||||
thisThread->quit();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
const float STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.10f;
|
||||
const float BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.20f;
|
||||
while (!_isFinished) {
|
||||
const float STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.10f;
|
||||
const float BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.20f;
|
||||
|
||||
const float RATIO_BACK_OFF = 0.02f;
|
||||
const float RATIO_BACK_OFF = 0.02f;
|
||||
|
||||
const float CURRENT_FRAME_RATIO = 1.0f / TRAILING_AVERAGE_FRAMES;
|
||||
const float PREVIOUS_FRAMES_RATIO = 1.0f - CURRENT_FRAME_RATIO;
|
||||
const float CURRENT_FRAME_RATIO = 1.0f / TRAILING_AVERAGE_FRAMES;
|
||||
const float PREVIOUS_FRAMES_RATIO = 1.0f - CURRENT_FRAME_RATIO;
|
||||
|
||||
if (_usecToSleep < 0) {
|
||||
_usecToSleep = 0;
|
||||
}
|
||||
if (usecToSleep < 0) {
|
||||
usecToSleep = 0;
|
||||
}
|
||||
|
||||
_trailingSleepRatio = (PREVIOUS_FRAMES_RATIO * _trailingSleepRatio)
|
||||
+ (_usecToSleep * CURRENT_FRAME_RATIO / (float) AudioConstants::NETWORK_FRAME_USECS);
|
||||
_trailingSleepRatio = (PREVIOUS_FRAMES_RATIO * _trailingSleepRatio)
|
||||
+ (usecToSleep * CURRENT_FRAME_RATIO / (float) AudioConstants::NETWORK_FRAME_USECS);
|
||||
|
||||
float lastCutoffRatio = _performanceThrottlingRatio;
|
||||
bool hasRatioChanged = false;
|
||||
float lastCutoffRatio = _performanceThrottlingRatio;
|
||||
bool hasRatioChanged = false;
|
||||
|
||||
if (_framesSinceCutoffEvent >= TRAILING_AVERAGE_FRAMES) {
|
||||
if (_trailingSleepRatio <= STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD) {
|
||||
// we're struggling - change our min required loudness to reduce some load
|
||||
_performanceThrottlingRatio = _performanceThrottlingRatio + (0.5f * (1.0f - _performanceThrottlingRatio));
|
||||
if (framesSinceCutoffEvent >= TRAILING_AVERAGE_FRAMES) {
|
||||
if (_trailingSleepRatio <= STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD) {
|
||||
// we're struggling - change our min required loudness to reduce some load
|
||||
_performanceThrottlingRatio = _performanceThrottlingRatio + (0.5f * (1.0f - _performanceThrottlingRatio));
|
||||
|
||||
qDebug() << "Mixer is struggling, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was"
|
||||
<< lastCutoffRatio << "and is now" << _performanceThrottlingRatio;
|
||||
hasRatioChanged = true;
|
||||
} else if (_trailingSleepRatio >= BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD && _performanceThrottlingRatio != 0) {
|
||||
// we've recovered and can back off the required loudness
|
||||
_performanceThrottlingRatio = _performanceThrottlingRatio - RATIO_BACK_OFF;
|
||||
qDebug() << "Mixer is struggling, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was"
|
||||
<< lastCutoffRatio << "and is now" << _performanceThrottlingRatio;
|
||||
hasRatioChanged = true;
|
||||
} else if (_trailingSleepRatio >= BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD && _performanceThrottlingRatio != 0) {
|
||||
// we've recovered and can back off the required loudness
|
||||
_performanceThrottlingRatio = _performanceThrottlingRatio - RATIO_BACK_OFF;
|
||||
|
||||
if (_performanceThrottlingRatio < 0) {
|
||||
_performanceThrottlingRatio = 0;
|
||||
if (_performanceThrottlingRatio < 0) {
|
||||
_performanceThrottlingRatio = 0;
|
||||
}
|
||||
|
||||
qDebug() << "Mixer is recovering, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was"
|
||||
<< lastCutoffRatio << "and is now" << _performanceThrottlingRatio;
|
||||
hasRatioChanged = true;
|
||||
}
|
||||
|
||||
qDebug() << "Mixer is recovering, sleeping" << _trailingSleepRatio * 100 << "% of frame time. Old cutoff was"
|
||||
<< lastCutoffRatio << "and is now" << _performanceThrottlingRatio;
|
||||
hasRatioChanged = true;
|
||||
}
|
||||
|
||||
if (hasRatioChanged) {
|
||||
// set out min audability threshold from the new ratio
|
||||
_minAudibilityThreshold = LOUDNESS_TO_DISTANCE_RATIO / (2.0f * (1.0f - _performanceThrottlingRatio));
|
||||
qDebug() << "Minimum audability required to be mixed is now" << _minAudibilityThreshold;
|
||||
if (hasRatioChanged) {
|
||||
// set out min audability threshold from the new ratio
|
||||
_minAudibilityThreshold = LOUDNESS_TO_DISTANCE_RATIO / (2.0f * (1.0f - _performanceThrottlingRatio));
|
||||
qDebug() << "Minimum audability required to be mixed is now" << _minAudibilityThreshold;
|
||||
|
||||
_framesSinceCutoffEvent = 0;
|
||||
framesSinceCutoffEvent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRatioChanged) {
|
||||
++_framesSinceCutoffEvent;
|
||||
}
|
||||
if (!hasRatioChanged) {
|
||||
++framesSinceCutoffEvent;
|
||||
}
|
||||
|
||||
quint64 now = usecTimestampNow();
|
||||
if (now - _lastPerSecondCallbackTime > USECS_PER_SECOND) {
|
||||
perSecondActions();
|
||||
_lastPerSecondCallbackTime = now;
|
||||
}
|
||||
quint64 now = usecTimestampNow();
|
||||
if (now - _lastPerSecondCallbackTime > USECS_PER_SECOND) {
|
||||
perSecondActions();
|
||||
_lastPerSecondCallbackTime = now;
|
||||
}
|
||||
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
|
||||
if (node->getLinkedData()) {
|
||||
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
|
||||
|
||||
|
@ -818,8 +807,8 @@ void AudioMixer::insideLoop() {
|
|||
char* mixDataAt;
|
||||
if (streamsMixed > 0) {
|
||||
// pack header
|
||||
int numBytesMixPacketHeader = populatePacketHeader(_clientMixBuffer, PacketTypeMixedAudio);
|
||||
mixDataAt = _clientMixBuffer + numBytesMixPacketHeader;
|
||||
int numBytesMixPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeMixedAudio);
|
||||
mixDataAt = clientMixBuffer + numBytesMixPacketHeader;
|
||||
|
||||
// pack sequence number
|
||||
quint16 sequence = nodeData->getOutgoingSequenceNumber();
|
||||
|
@ -831,8 +820,8 @@ void AudioMixer::insideLoop() {
|
|||
mixDataAt += AudioConstants::NETWORK_FRAME_BYTES_STEREO;
|
||||
} else {
|
||||
// pack header
|
||||
int numBytesPacketHeader = populatePacketHeader(_clientMixBuffer, PacketTypeSilentAudioFrame);
|
||||
mixDataAt = _clientMixBuffer + numBytesPacketHeader;
|
||||
int numBytesPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeSilentAudioFrame);
|
||||
mixDataAt = clientMixBuffer + numBytesPacketHeader;
|
||||
|
||||
// pack sequence number
|
||||
quint16 sequence = nodeData->getOutgoingSequenceNumber();
|
||||
|
@ -844,12 +833,12 @@ void AudioMixer::insideLoop() {
|
|||
memcpy(mixDataAt, &numSilentSamples, sizeof(quint16));
|
||||
mixDataAt += sizeof(quint16);
|
||||
}
|
||||
|
||||
|
||||
// Send audio environment
|
||||
sendAudioEnvironmentPacket(node);
|
||||
|
||||
// send mixed audio packet
|
||||
nodeList->writeDatagram(_clientMixBuffer, mixDataAt - _clientMixBuffer, node);
|
||||
nodeList->writeDatagram(clientMixBuffer, mixDataAt - clientMixBuffer, node);
|
||||
nodeData->incrementOutgoingMixedAudioSequenceNumber();
|
||||
|
||||
// send an audio stream stats packet if it's time
|
||||
|
@ -863,22 +852,22 @@ void AudioMixer::insideLoop() {
|
|||
}
|
||||
});
|
||||
|
||||
++_numStatFrames;
|
||||
++_numStatFrames;
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
if (_isFinished) {
|
||||
return;
|
||||
}
|
||||
if (_isFinished) {
|
||||
break;
|
||||
}
|
||||
|
||||
_usecToSleep = (++_nextFrame * AudioConstants::NETWORK_FRAME_USECS) - _timer.nsecsElapsed() / 1000; // ns to us
|
||||
usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - timer.nsecsElapsed() / 1000; // ns to us
|
||||
|
||||
if (_usecToSleep > 0) {
|
||||
usleep(_usecToSleep);
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AudioMixer::perSecondActions() {
|
||||
_sendAudioStreamStats = true;
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ public:
|
|||
public slots:
|
||||
/// threaded run of assignment
|
||||
void run();
|
||||
void insideLoop();
|
||||
|
||||
void readPendingDatagrams() { }; // this will not be called since our datagram processing thread will handle
|
||||
void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr);
|
||||
|
@ -112,14 +111,14 @@ private:
|
|||
|
||||
MovingMinMaxAvg<int> _readPendingCallsPerSecondStats; // update with # of readPendingDatagrams calls in the last second
|
||||
|
||||
// loop variables
|
||||
QTimer* _idleTimer = nullptr;
|
||||
int _nextFrame = 0;
|
||||
QElapsedTimer _timer;
|
||||
char _clientMixBuffer[MAX_PACKET_SIZE];
|
||||
int _usecToSleep = AudioConstants::NETWORK_FRAME_USECS;
|
||||
const int TRAILING_AVERAGE_FRAMES = 100;
|
||||
int _framesSinceCutoffEvent = TRAILING_AVERAGE_FRAMES;
|
||||
/* // loop variables */
|
||||
/* // QTimer* _idleTimer = nullptr; */
|
||||
/* int _nextFrame = 0; */
|
||||
/* QElapsedTimer _timer; */
|
||||
/* char _clientMixBuffer[MAX_PACKET_SIZE]; */
|
||||
/* int _usecToSleep = AudioConstants::NETWORK_FRAME_USECS; */
|
||||
/* const int TRAILING_AVERAGE_FRAMES = 100; */
|
||||
/* int _framesSinceCutoffEvent = TRAILING_AVERAGE_FRAMES; */
|
||||
};
|
||||
|
||||
#endif // hifi_AudioMixer_h
|
||||
|
|
|
@ -45,6 +45,10 @@ AvatarMixer::AvatarMixer(const QByteArray& packet) :
|
|||
}
|
||||
|
||||
AvatarMixer::~AvatarMixer() {
|
||||
qDebug() << "AvatarMixer::~AvatarMixer";
|
||||
if (_broadcastTimer) {
|
||||
_broadcastTimer->deleteLater();
|
||||
}
|
||||
_broadcastThread.quit();
|
||||
_broadcastThread.wait();
|
||||
}
|
||||
|
@ -61,9 +65,7 @@ const float BILLBOARD_AND_IDENTITY_SEND_PROBABILITY = 1.0f / 300.0f;
|
|||
// 1) use the view frustum to cull those avatars that are out of view. Since avatar data doesn't need to be present
|
||||
// if the avatar is not in view or in the keyhole.
|
||||
void AvatarMixer::broadcastAvatarData() {
|
||||
|
||||
int idleTime = QDateTime::currentMSecsSinceEpoch() - _lastFrameTimestamp;
|
||||
|
||||
++_numStatFrames;
|
||||
|
||||
const float STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.10f;
|
||||
|
@ -334,6 +336,22 @@ void AvatarMixer::sendStatsPacket() {
|
|||
_numStatFrames = 0;
|
||||
}
|
||||
|
||||
// void AvatarMixer::stop() {
|
||||
// qDebug() << "AvatarMixer::stop";
|
||||
// if (_broadcastTimer) {
|
||||
// // _broadcastTimer->stop();
|
||||
// // delete _broadcastTimer;
|
||||
// _broadcastTimer->deleteLater();
|
||||
// // _broadcastTimer = nullptr;
|
||||
// }
|
||||
|
||||
// _broadcastThread.quit();
|
||||
// _broadcastThread.wait();
|
||||
|
||||
// ThreadedAssignment::stop();
|
||||
// }
|
||||
|
||||
|
||||
void AvatarMixer::run() {
|
||||
ThreadedAssignment::commonInit(AVATAR_MIXER_LOGGING_NAME, NodeType::AvatarMixer);
|
||||
|
||||
|
@ -343,13 +361,13 @@ void AvatarMixer::run() {
|
|||
nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
|
||||
|
||||
// setup the timer that will be fired on the broadcast thread
|
||||
QTimer* broadcastTimer = new QTimer();
|
||||
broadcastTimer->setInterval(AVATAR_DATA_SEND_INTERVAL_MSECS);
|
||||
broadcastTimer->moveToThread(&_broadcastThread);
|
||||
_broadcastTimer = new QTimer();
|
||||
_broadcastTimer->setInterval(AVATAR_DATA_SEND_INTERVAL_MSECS);
|
||||
_broadcastTimer->moveToThread(&_broadcastThread);
|
||||
|
||||
// connect appropriate signals and slots
|
||||
connect(broadcastTimer, &QTimer::timeout, this, &AvatarMixer::broadcastAvatarData, Qt::DirectConnection);
|
||||
connect(&_broadcastThread, SIGNAL(started()), broadcastTimer, SLOT(start()));
|
||||
connect(_broadcastTimer, &QTimer::timeout, this, &AvatarMixer::broadcastAvatarData, Qt::DirectConnection);
|
||||
connect(&_broadcastThread, SIGNAL(started()), _broadcastTimer, SLOT(start()));
|
||||
|
||||
// start the broadcastThread
|
||||
_broadcastThread.start();
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
public slots:
|
||||
/// runs the avatar mixer
|
||||
void run();
|
||||
// Q_INVOKABLE virtual void stop();
|
||||
|
||||
void nodeAdded(SharedNodePointer nodeAdded);
|
||||
void nodeKilled(SharedNodePointer killedNode);
|
||||
|
@ -32,6 +33,8 @@ public slots:
|
|||
void readPendingDatagrams();
|
||||
|
||||
void sendStatsPacket();
|
||||
|
||||
void finished();
|
||||
|
||||
private:
|
||||
void broadcastAvatarData();
|
||||
|
@ -47,6 +50,8 @@ private:
|
|||
int _numStatFrames;
|
||||
int _sumBillboardPackets;
|
||||
int _sumIdentityPackets;
|
||||
|
||||
QTimer* _broadcastTimer = nullptr;
|
||||
};
|
||||
|
||||
#endif // hifi_AvatarMixer_h
|
||||
|
|
|
@ -27,6 +27,13 @@ EntityServer::EntityServer(const QByteArray& packet)
|
|||
}
|
||||
|
||||
EntityServer::~EntityServer() {
|
||||
qDebug() << "EntityServer::~EntityServer";
|
||||
|
||||
if (_pruneDeletedEntitiesTimer) {
|
||||
_pruneDeletedEntitiesTimer->stop();
|
||||
_pruneDeletedEntitiesTimer->deleteLater();
|
||||
}
|
||||
|
||||
EntityTree* tree = (EntityTree*)_tree;
|
||||
tree->removeNewlyCreatedHook(this);
|
||||
}
|
||||
|
@ -48,10 +55,10 @@ Octree* EntityServer::createTree() {
|
|||
}
|
||||
|
||||
void EntityServer::beforeRun() {
|
||||
QTimer* pruneDeletedEntitiesTimer = new QTimer(this);
|
||||
connect(pruneDeletedEntitiesTimer, SIGNAL(timeout()), this, SLOT(pruneDeletedEntities()));
|
||||
_pruneDeletedEntitiesTimer = new QTimer(this);
|
||||
connect(_pruneDeletedEntitiesTimer, SIGNAL(timeout()), this, SLOT(pruneDeletedEntities()));
|
||||
const int PRUNE_DELETED_MODELS_INTERVAL_MSECS = 1 * 1000; // once every second
|
||||
pruneDeletedEntitiesTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS);
|
||||
_pruneDeletedEntitiesTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS);
|
||||
}
|
||||
|
||||
void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) {
|
||||
|
@ -158,3 +165,12 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio
|
|||
}
|
||||
|
||||
|
||||
// void EntityServer::stop() {
|
||||
// qDebug() << "EntityServer::stop";
|
||||
// if (_pruneDeletedEntitiesTimer) {
|
||||
// _pruneDeletedEntitiesTimer->stop();
|
||||
// delete _pruneDeletedEntitiesTimer;
|
||||
// _pruneDeletedEntitiesTimer = nullptr;
|
||||
// }
|
||||
// OctreeServer::stop();
|
||||
// }
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
virtual void readAdditionalConfiguration(const QJsonObject& settingsSectionObject);
|
||||
|
||||
public slots:
|
||||
// Q_INVOKABLE virtual void stop();
|
||||
void pruneDeletedEntities();
|
||||
|
||||
protected:
|
||||
|
@ -51,6 +52,7 @@ protected:
|
|||
|
||||
private:
|
||||
EntitySimulation* _entitySimulation;
|
||||
QTimer* _pruneDeletedEntitiesTimer = nullptr;
|
||||
};
|
||||
|
||||
#endif // hifi_EntityServer_h
|
||||
|
|
|
@ -74,7 +74,8 @@ public:
|
|||
|
||||
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
|
||||
|
||||
void shuttingDown() { _shuttingDown = true;}
|
||||
// void shuttingDown() { _shuttingDown = true;}
|
||||
virtual void terminating() { _shuttingDown = true; ReceivedPacketProcessor::terminating(); }
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -266,16 +266,19 @@ OctreeServer::~OctreeServer() {
|
|||
}
|
||||
|
||||
if (_jurisdictionSender) {
|
||||
_jurisdictionSender->terminating();
|
||||
_jurisdictionSender->terminate();
|
||||
_jurisdictionSender->deleteLater();
|
||||
}
|
||||
|
||||
if (_octreeInboundPacketProcessor) {
|
||||
_octreeInboundPacketProcessor->terminating();
|
||||
_octreeInboundPacketProcessor->terminate();
|
||||
_octreeInboundPacketProcessor->deleteLater();
|
||||
}
|
||||
|
||||
if (_persistThread) {
|
||||
_persistThread->terminating();
|
||||
_persistThread->terminate();
|
||||
_persistThread->deleteLater();
|
||||
}
|
||||
|
@ -1219,7 +1222,7 @@ void OctreeServer::forceNodeShutdown(SharedNodePointer node) {
|
|||
void OctreeServer::aboutToFinish() {
|
||||
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
|
||||
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
|
||||
_octreeInboundPacketProcessor->shuttingDown();
|
||||
_octreeInboundPacketProcessor->terminating();
|
||||
|
||||
DependencyManager::get<NodeList>()->eachNode([this](const SharedNodePointer& node) {
|
||||
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
|
||||
|
@ -1233,6 +1236,40 @@ void OctreeServer::aboutToFinish() {
|
|||
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
|
||||
}
|
||||
|
||||
|
||||
// void OctreeServer::stop() {
|
||||
// qDebug() << "OctreeServer::stop";
|
||||
// // setFinished(true);
|
||||
// // QThread *thisThread = QThread::currentThread();
|
||||
// // thisThread->quit();
|
||||
|
||||
// if (_jurisdictionSender) {
|
||||
// _jurisdictionSender->terminating();
|
||||
// _jurisdictionSender->terminate();
|
||||
// // delete _jurisdictionSender;
|
||||
// // _jurisdictionSender = nullptr;
|
||||
// }
|
||||
|
||||
// _datagramProcessingThread->quit();
|
||||
// if (_octreeInboundPacketProcessor) {
|
||||
// _octreeInboundPacketProcessor->terminating();
|
||||
// _octreeInboundPacketProcessor->terminate();
|
||||
// // delete _octreeInboundPacketProcessor;
|
||||
// // _octreeInboundPacketProcessor = nullptr;
|
||||
// }
|
||||
|
||||
// // _persistThread
|
||||
// if (_persistThread) {
|
||||
// _persistThread->terminating();
|
||||
// _persistThread->terminate();
|
||||
// // delete _persistThread;
|
||||
// // _persistThread = nullptr;
|
||||
// }
|
||||
|
||||
// ThreadedAssignment::stop();
|
||||
// }
|
||||
|
||||
|
||||
QString OctreeServer::getUptime() {
|
||||
QString formattedUptime;
|
||||
quint64 now = usecTimestampNow();
|
||||
|
|
|
@ -123,6 +123,7 @@ public:
|
|||
public slots:
|
||||
/// runs the octree server assignment
|
||||
void run();
|
||||
// Q_INVOKABLE virtual void stop();
|
||||
void nodeAdded(SharedNodePointer node);
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
void sendStatsPacket();
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
/// How many received packets waiting are to be processed
|
||||
int packetsToProcessCount() const { return _packets.size(); }
|
||||
|
||||
virtual void terminating();
|
||||
|
||||
public slots:
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
|
@ -71,8 +73,6 @@ protected:
|
|||
/// Override to do work after the packets processing loop. Default does nothing.
|
||||
virtual void postProcess() { }
|
||||
|
||||
virtual void terminating();
|
||||
|
||||
protected:
|
||||
|
||||
QVector<NetworkPacket> _packets;
|
||||
|
|
|
@ -26,7 +26,14 @@ ThreadedAssignment::ThreadedAssignment(const QByteArray& packet) :
|
|||
|
||||
}
|
||||
|
||||
ThreadedAssignment::~ThreadedAssignment() {
|
||||
// setFinished(true);
|
||||
}
|
||||
|
||||
void ThreadedAssignment::setFinished(bool isFinished) {
|
||||
|
||||
qDebug() << "------------- ThreadedAssignment::setFinished" << isFinished << " -------------------";
|
||||
|
||||
_isFinished = isFinished;
|
||||
|
||||
if (_isFinished) {
|
||||
|
@ -50,8 +57,10 @@ void ThreadedAssignment::setFinished(bool isFinished) {
|
|||
|
||||
if (_datagramProcessingThread) {
|
||||
// tell the datagram processing thread to quit and wait until it is done, then return the node socket to the NodeList
|
||||
qDebug() << "stopping datagramProcessingThread...";
|
||||
_datagramProcessingThread->quit();
|
||||
_datagramProcessingThread->wait();
|
||||
qDebug() << "done stopping datagramProcessingThread.";
|
||||
|
||||
// set node socket parent back to NodeList
|
||||
nodeList->getNodeSocket().setParent(nodeList.data());
|
||||
|
@ -64,6 +73,15 @@ void ThreadedAssignment::setFinished(bool isFinished) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// void ThreadedAssignment::stop() {
|
||||
// setFinished(true);
|
||||
// qDebug() << "ThreadedAssignment::stop";
|
||||
// QThread *thisThread = QThread::currentThread();
|
||||
// thisThread->quit();
|
||||
// }
|
||||
|
||||
|
||||
void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeType, bool shouldSendStats) {
|
||||
// change the logging target name while the assignment is running
|
||||
LogHandler::getInstance().setTargetName(targetName);
|
||||
|
|
|
@ -20,6 +20,7 @@ class ThreadedAssignment : public Assignment {
|
|||
Q_OBJECT
|
||||
public:
|
||||
ThreadedAssignment(const QByteArray& packet);
|
||||
virtual ~ThreadedAssignment();
|
||||
|
||||
void setFinished(bool isFinished);
|
||||
virtual void aboutToFinish() { };
|
||||
|
@ -28,14 +29,13 @@ public:
|
|||
public slots:
|
||||
/// threaded run of assignment
|
||||
virtual void run() = 0;
|
||||
Q_INVOKABLE void stop() { setFinished(true); }
|
||||
Q_INVOKABLE virtual void stop() { setFinished(true); }
|
||||
virtual void readPendingDatagrams() = 0;
|
||||
virtual void sendStatsPacket();
|
||||
|
||||
public slots:
|
||||
virtual void aboutToQuit() {
|
||||
// emit finished();
|
||||
QMetaObject::invokeMethod(this, "stop");
|
||||
QMetaObject::invokeMethod(this, "stop");
|
||||
}
|
||||
|
||||
signals:
|
||||
|
|
|
@ -228,6 +228,7 @@ void OctreePersistThread::aboutToFinish() {
|
|||
qCDebug(octree) << "Persist thread about to finish...";
|
||||
persist();
|
||||
qCDebug(octree) << "Persist thread done with about to finish...";
|
||||
_stopThread = true;
|
||||
}
|
||||
|
||||
void OctreePersistThread::persist() {
|
||||
|
|
|
@ -26,15 +26,21 @@
|
|||
class Dependency {
|
||||
public:
|
||||
typedef std::function<void(Dependency* pointer)> DeleterFunction;
|
||||
const QString& getDependencyName() { return _name; }
|
||||
|
||||
protected:
|
||||
virtual ~Dependency() {}
|
||||
virtual ~Dependency() {
|
||||
qDebug() << "DESTRUCTING" << _name;
|
||||
}
|
||||
virtual void customDeleter() {
|
||||
_customDeleter(this);
|
||||
}
|
||||
|
||||
void setCustomDeleter(DeleterFunction customDeleter) { _customDeleter = customDeleter; }
|
||||
DeleterFunction _customDeleter = [](Dependency* pointer) { delete pointer; };
|
||||
|
||||
void setDependencyName(QString name) { _name = name; }
|
||||
QString _name;
|
||||
|
||||
friend class DependencyManager;
|
||||
};
|
||||
|
@ -95,6 +101,7 @@ QSharedPointer<T> DependencyManager::set(Args&&... args) {
|
|||
QSharedPointer<T> newInstance(new T(args...), &T::customDeleter);
|
||||
QSharedPointer<Dependency> storedInstance = qSharedPointerCast<Dependency>(newInstance);
|
||||
instance.swap(storedInstance);
|
||||
newInstance->setDependencyName(typeid(T).name());
|
||||
|
||||
return newInstance;
|
||||
}
|
||||
|
@ -102,6 +109,7 @@ QSharedPointer<T> DependencyManager::set(Args&&... args) {
|
|||
template <typename T>
|
||||
void DependencyManager::destroy() {
|
||||
static size_t hashCode = _manager.getHashCode<T>();
|
||||
qDebug() << "DESTROYING" << _manager.safeGet(hashCode)->getDependencyName();
|
||||
_manager.safeGet(hashCode).clear();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue