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();
PathUtils::removeTemporaryApplicationDirs("Oven"); 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(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.unregisterListener(this);
packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet"); packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet");
packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo"); packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo");
packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload"); packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload");
@ -428,11 +428,30 @@ void AssetServer::completeSetup() {
} }
void AssetServer::queueRequests(QSharedPointer<ReceivedMessage> packet, SharedNodePointer senderNode) { void AssetServer::queueRequests(QSharedPointer<ReceivedMessage> packet, SharedNodePointer senderNode) {
qCDebug(asset_server) << "Queuing requests until fully setup";
QMutexLocker lock { &_queuedRequestsMutex };
_queuedRequests.push_back({ packet, senderNode }); _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() { 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()) { switch (request.first->getType()) {
case PacketType::AssetGet: case PacketType::AssetGet:
handleAssetGet(request.first, request.second); handleAssetGet(request.first, request.second);
@ -447,11 +466,10 @@ void AssetServer::replayRequests() {
handleAssetMappingOperation(request.first, request.second); handleAssetMappingOperation(request.first, request.second);
break; break;
default: default:
qWarning() << "Unknown queued request type:" << request.first->getType(); qCWarning(asset_server) << "Unknown queued request type:" << request.first->getType();
break; break;
} }
} }
_queuedRequests.clear();
} }
void AssetServer::cleanupUnmappedFiles() { void AssetServer::cleanupUnmappedFiles() {

View file

@ -123,7 +123,10 @@ private:
QHash<AssetUtils::AssetHash, std::shared_ptr<BakeAssetTask>> _pendingBakes; QHash<AssetUtils::AssetHash, std::shared_ptr<BakeAssetTask>> _pendingBakes;
QThreadPool _bakingTaskPool; 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 _wasColorTextureCompressionEnabled { false };
bool _wasGrayscaleTextureCompressionEnabled { false }; bool _wasGrayscaleTextureCompressionEnabled { false };