Fix race condition in Asset Server

This commit is contained in:
Atlante45 2018-02-15 18:16:30 -08:00
parent 697f0c443c
commit f6e9d2c6dd
2 changed files with 27 additions and 6 deletions

View file

@ -416,9 +416,9 @@ void AssetServer::completeSetup() {
PathUtils::removeTemporaryApplicationDirs();
PathUtils::removeTemporaryApplicationDirs("Oven");
// We're fully setup, remove the request queueing and replay all requests
qCDebug(asset_server) << "Overriding temporary queuing packet handler.";
// We're fully setup, override the request queueing handler and replay all requests
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.unregisterListener(this);
packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet");
packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo");
packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload");
@ -428,11 +428,30 @@ void AssetServer::completeSetup() {
}
void AssetServer::queueRequests(QSharedPointer<ReceivedMessage> packet, SharedNodePointer senderNode) {
qCDebug(asset_server) << "Queuing requests until fully setup";
QMutexLocker lock { &_queuedRequestsMutex };
_queuedRequests.push_back({ packet, senderNode });
// If we've stopped queueing but the callback was already in flight,
// then replay it immediately.
if (!_isQueueingRequests) {
lock.unlock();
replayRequests();
}
}
void AssetServer::replayRequests() {
for (const auto& request : _queuedRequests) {
RequestQueue queue;
{
QMutexLocker lock { &_queuedRequestsMutex };
qSwap(queue, _queuedRequests);
_isQueueingRequests = false;
}
qCDebug(asset_server) << "Replaying" << queue.size() << "requests.";
for (const auto& request : queue) {
switch (request.first->getType()) {
case PacketType::AssetGet:
handleAssetGet(request.first, request.second);
@ -447,11 +466,10 @@ void AssetServer::replayRequests() {
handleAssetMappingOperation(request.first, request.second);
break;
default:
qWarning() << "Unknown queued request type:" << request.first->getType();
qCWarning(asset_server) << "Unknown queued request type:" << request.first->getType();
break;
}
}
_queuedRequests.clear();
}
void AssetServer::cleanupUnmappedFiles() {

View file

@ -123,7 +123,10 @@ private:
QHash<AssetUtils::AssetHash, std::shared_ptr<BakeAssetTask>> _pendingBakes;
QThreadPool _bakingTaskPool;
QVector<QPair<QSharedPointer<ReceivedMessage>, SharedNodePointer>> _queuedRequests;
QMutex _queuedRequestsMutex;
bool _isQueueingRequests { true };
using RequestQueue = QVector<QPair<QSharedPointer<ReceivedMessage>, SharedNodePointer>>;
RequestQueue _queuedRequests;
bool _wasColorTextureCompressionEnabled { false };
bool _wasGrayscaleTextureCompressionEnabled { false };