From c939385809062a26b23fad9be7c4062b1bf610a1 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 29 Sep 2014 19:40:48 +0300 Subject: [PATCH] Delay opening the resource file until loading actually starts Opening it when the load is queued can cause large numbers of open files to be created at once and dissipate slowly as the queue is processed. --- source/resourcemanager.cpp | 24 ++++++++++++++---------- source/resourcemanager.h | 10 +++++++++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/source/resourcemanager.cpp b/source/resourcemanager.cpp index cdd03226..c9cbcbb7 100644 --- a/source/resourcemanager.cpp +++ b/source/resourcemanager.cpp @@ -78,15 +78,17 @@ void ResourceManager::load_resource(Resource &r) if(!managed.collection) throw runtime_error("no location"); - if(managed.loader) + if(managed.state!=ManagedResource::NOT_LOADED) return; - managed.start_loading(); - if(async_loads) + { + managed.state = ManagedResource::LOAD_QUEUED; queue.push_back(&managed); + } else { + managed.start_loading(); while(!managed.loader->process()) ; managed.finish_loading(); } @@ -95,7 +97,7 @@ void ResourceManager::load_resource(Resource &r) void ResourceManager::resource_used(const Resource &r) { ManagedResource *managed = reinterpret_cast(r.get_manager_data()); - if(!managed->loaded && !managed->loader && policy!=LOAD_MANUALLY) + if(managed->state==ManagedResource::NOT_LOADED && policy!=LOAD_MANUALLY) load_resource(*managed->resource); managed->last_used = frame; @@ -145,7 +147,7 @@ void ResourceManager::tick() next_unload = 0; for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i) - if(i->second.loaded) + if(i->second.state==ManagedResource::LOADED) { if(i->second.last_used<=unload_limit) i->second.unload(); @@ -165,7 +167,7 @@ void ResourceManager::tick() ManagedResource *best = 0; UInt64 best_impact = 0; for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i) - if(i->second.loaded && i->second.last_usedsecond.state==ManagedResource::LOADED && i->second.last_usedsecond.data_size*(frame-i->second.last_used); if(!best || impact>best_impact) @@ -187,7 +189,7 @@ UInt64 ResourceManager::get_total_data_size() const { UInt64 total = 0; for(ResourceMap::const_iterator i=resources.begin(); i!=resources.end(); ++i) - if(i->second.loaded) + if(i->second.state==ManagedResource::LOADED) total += i->second.data_size; return total; } @@ -198,7 +200,7 @@ ResourceManager::ManagedResource::ManagedResource(Resource &r): collection(0), io(0), loader(0), - loaded(false), + state(NOT_LOADED), last_used(0), data_size(0) { } @@ -213,13 +215,14 @@ void ResourceManager::ManagedResource::start_loading() io = 0; throw logic_error("no loader created"); } + state = LOADING; } void ResourceManager::ManagedResource::finish_loading() { delete loader; loader = 0; - loaded = true; + state = LOADED; delete io; io = 0; data_size = resource->get_data_size(); @@ -231,7 +234,7 @@ void ResourceManager::ManagedResource::finish_loading() void ResourceManager::ManagedResource::unload() { resource->unload(); - loaded = false; + state = NOT_LOADED; for(vector::const_iterator i=watchers.begin(); i!=watchers.end(); ++i) (*i)->resource_unloaded(*resource); @@ -292,6 +295,7 @@ void ResourceManager::LoadingThread::set_resource(ManagedResource *r) } resource = r; + resource->start_loading(); state = BUSY; sem.signal(); } diff --git a/source/resourcemanager.h b/source/resourcemanager.h index f5ccac3b..244c67ec 100644 --- a/source/resourcemanager.h +++ b/source/resourcemanager.h @@ -26,12 +26,20 @@ public: private: struct ManagedResource { + enum ResourceState + { + NOT_LOADED, + LOAD_QUEUED, + LOADING, + LOADED + }; + Resource *resource; DataFile::Collection *collection; std::string name; IO::Seekable *io; Resource::AsyncLoader *loader; - bool loaded; + ResourceState state; unsigned last_used; UInt64 data_size; std::vector watchers; -- 2.45.2