mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 22:51:20 +02:00
Merge pull request #7392 from jherico/resource
Make shared lists thread safe
This commit is contained in:
commit
5e8c10508c
2 changed files with 89 additions and 36 deletions
|
@ -159,44 +159,45 @@ void ResourceCache::clearUnusedResource() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceCache::attemptRequest(Resource* resource) {
|
void ResourceCacheSharedItems::appendActiveRequest(Resource* resource) {
|
||||||
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
Lock lock(_mutex);
|
||||||
|
_loadingRequests.append(resource);
|
||||||
// Disable request limiting for ATP
|
|
||||||
if (resource->getURL().scheme() != URL_SCHEME_ATP) {
|
|
||||||
if (_requestsActive >= _requestLimit) {
|
|
||||||
// wait until a slot becomes available
|
|
||||||
sharedItems->_pendingRequests.append(resource);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
++_requestsActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
sharedItems->_loadingRequests.append(resource);
|
|
||||||
resource->makeRequest();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::requestCompleted(Resource* resource) {
|
void ResourceCacheSharedItems::appendPendingRequest(Resource* resource) {
|
||||||
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
Lock lock(_mutex);
|
||||||
sharedItems->_loadingRequests.removeOne(resource);
|
_pendingRequests.append(resource);
|
||||||
if (resource->getURL().scheme() != URL_SCHEME_ATP) {
|
|
||||||
--_requestsActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
attemptHighestPriorityRequest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceCache::attemptHighestPriorityRequest() {
|
QList<QPointer<Resource>> ResourceCacheSharedItems::getPendingRequests() const {
|
||||||
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
Lock lock(_mutex);
|
||||||
|
return _pendingRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ResourceCacheSharedItems::getPendingRequestsCount() const {
|
||||||
|
Lock lock(_mutex);
|
||||||
|
return _pendingRequests.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Resource*> ResourceCacheSharedItems::getLoadingRequests() const {
|
||||||
|
Lock lock(_mutex);
|
||||||
|
return _loadingRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCacheSharedItems::removeRequest(Resource* resource) {
|
||||||
|
Lock lock(_mutex);
|
||||||
|
_loadingRequests.removeOne(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource* ResourceCacheSharedItems::getHighestPendingRequest() {
|
||||||
|
Lock lock(_mutex);
|
||||||
// look for the highest priority pending request
|
// look for the highest priority pending request
|
||||||
int highestIndex = -1;
|
int highestIndex = -1;
|
||||||
float highestPriority = -FLT_MAX;
|
float highestPriority = -FLT_MAX;
|
||||||
for (int i = 0; i < sharedItems->_pendingRequests.size(); ) {
|
for (int i = 0; i < _pendingRequests.size();) {
|
||||||
Resource* resource = sharedItems->_pendingRequests.at(i).data();
|
Resource* resource = _pendingRequests.at(i).data();
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
sharedItems->_pendingRequests.removeAt(i);
|
_pendingRequests.removeAt(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
float priority = resource->getLoadPriority();
|
float priority = resource->getLoadPriority();
|
||||||
|
@ -206,7 +207,45 @@ bool ResourceCache::attemptHighestPriorityRequest() {
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return (highestIndex >= 0) && attemptRequest(sharedItems->_pendingRequests.takeAt(highestIndex));
|
if (highestIndex >= 0) {
|
||||||
|
return _pendingRequests.takeAt(highestIndex);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceCache::attemptRequest(Resource* resource) {
|
||||||
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
|
|
||||||
|
// Disable request limiting for ATP
|
||||||
|
if (resource->getURL().scheme() != URL_SCHEME_ATP) {
|
||||||
|
if (_requestsActive >= _requestLimit) {
|
||||||
|
// wait until a slot becomes available
|
||||||
|
sharedItems->appendPendingRequest(resource);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
++_requestsActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedItems->appendActiveRequest(resource);
|
||||||
|
resource->makeRequest();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCache::requestCompleted(Resource* resource) {
|
||||||
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
|
sharedItems->removeRequest(resource);
|
||||||
|
if (resource->getURL().scheme() != URL_SCHEME_ATP) {
|
||||||
|
--_requestsActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
attemptHighestPriorityRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceCache::attemptHighestPriorityRequest() {
|
||||||
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
|
auto resource = sharedItems->getHighestPendingRequest();
|
||||||
|
return (resource && attemptRequest(resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
const int DEFAULT_REQUEST_LIMIT = 10;
|
const int DEFAULT_REQUEST_LIMIT = 10;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#ifndef hifi_ResourceCache_h
|
#ifndef hifi_ResourceCache_h
|
||||||
#define hifi_ResourceCache_h
|
#define hifi_ResourceCache_h
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
#include <QtCore/QHash>
|
#include <QtCore/QHash>
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
@ -53,12 +54,25 @@ static const qint64 MAX_UNUSED_MAX_SIZE = 10 * BYTES_PER_GIGABYTES;
|
||||||
// object instead
|
// object instead
|
||||||
class ResourceCacheSharedItems : public Dependency {
|
class ResourceCacheSharedItems : public Dependency {
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
|
using Mutex = std::mutex;
|
||||||
|
using Lock = std::unique_lock<Mutex>;
|
||||||
public:
|
public:
|
||||||
QList<QPointer<Resource>> _pendingRequests;
|
void appendPendingRequest(Resource* newRequest);
|
||||||
QList<Resource*> _loadingRequests;
|
void appendActiveRequest(Resource* newRequest);
|
||||||
|
void removeRequest(Resource* doneRequest);
|
||||||
|
QList<QPointer<Resource>> getPendingRequests() const;
|
||||||
|
uint32_t getPendingRequestsCount() const;
|
||||||
|
QList<Resource*> getLoadingRequests() const;
|
||||||
|
Resource* getHighestPendingRequest();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResourceCacheSharedItems() { }
|
ResourceCacheSharedItems() { }
|
||||||
virtual ~ResourceCacheSharedItems() { }
|
virtual ~ResourceCacheSharedItems() { }
|
||||||
|
|
||||||
|
mutable Mutex _mutex;
|
||||||
|
QList<QPointer<Resource>> _pendingRequests;
|
||||||
|
QList<Resource*> _loadingRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,11 +89,11 @@ public:
|
||||||
void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize);
|
void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize);
|
||||||
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
||||||
|
|
||||||
static const QList<Resource*>& getLoadingRequests()
|
static const QList<Resource*> getLoadingRequests()
|
||||||
{ return DependencyManager::get<ResourceCacheSharedItems>()->_loadingRequests; }
|
{ return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests(); }
|
||||||
|
|
||||||
static int getPendingRequestCount()
|
static int getPendingRequestCount()
|
||||||
{ return DependencyManager::get<ResourceCacheSharedItems>()->_pendingRequests.size(); }
|
{ return DependencyManager::get<ResourceCacheSharedItems>()->getPendingRequestsCount(); }
|
||||||
|
|
||||||
ResourceCache(QObject* parent = NULL);
|
ResourceCache(QObject* parent = NULL);
|
||||||
virtual ~ResourceCache();
|
virtual ~ResourceCache();
|
||||||
|
|
Loading…
Reference in a new issue