From: Mikko Rasa Date: Fri, 4 Dec 2015 09:36:07 +0000 (+0200) Subject: Make ResourceManager thread-safe X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=5ef508ffc324d4f00239555c0566e4c1f2c9c5c4 Make ResourceManager thread-safe Since a big part of the class is loading resources asynchronously, it makes sense that resources can also be created from another thread. --- diff --git a/source/resourcemanager.cpp b/source/resourcemanager.cpp index bcc4839b..52e5866a 100644 --- a/source/resourcemanager.cpp +++ b/source/resourcemanager.cpp @@ -66,12 +66,20 @@ void ResourceManager::set_max_retain_frames(unsigned f) void ResourceManager::add_resource(Resource &r) { + MutexLock lock(map_mutex); insert_unique(resources, &r, ManagedResource(r)); } -void *ResourceManager::get_data_for_resource(const Resource &r) +const ResourceManager::ManagedResource &ResourceManager::get_managed_resource(const Resource &r) const { - return &get_item(resources, &r); + MutexLock lock(map_mutex); + return get_item(resources, &r); +} + +ResourceManager::ManagedResource &ResourceManager::get_managed_resource(const Resource &r) +{ + MutexLock lock(map_mutex); + return get_item(resources, &r); } void ResourceManager::set_resource_location(Resource &r, DataFile::Collection &c, const string &n) @@ -81,8 +89,11 @@ void ResourceManager::set_resource_location(Resource &r, DataFile::Collection &c void ResourceManager::set_resource_location(Resource &r, const ResourceLocation &l) { - ManagedResource &managed = get_item(resources, &r); - managed.location = l; + { + MutexLock lock(map_mutex); + ManagedResource &managed = get_item(resources, &r); + managed.location = l; + } if(policy==LOAD_IMMEDIATELY) load_resource(r); @@ -90,13 +101,13 @@ void ResourceManager::set_resource_location(Resource &r, const ResourceLocation const ResourceManager::ResourceLocation *ResourceManager::get_resource_location(const Resource &r) const { - const ManagedResource &managed = get_item(resources, &r); + const ManagedResource &managed = get_managed_resource(r); return managed.location.collection ? &managed.location : 0; } void ResourceManager::load_resource(Resource &r) { - ManagedResource &managed = get_item(resources, &r); + ManagedResource &managed = get_managed_resource(r); if(!managed.location.collection) throw runtime_error("no location"); @@ -139,7 +150,7 @@ void ResourceManager::resource_used(const Resource &r) void ResourceManager::remove_resource(Resource &r) { - ManagedResource &managed = get_item(resources, &r); + ManagedResource &managed = get_managed_resource(r); ManagedResource::State state = managed.state; if(state==ManagedResource::LOAD_QUEUED) { @@ -149,17 +160,19 @@ void ResourceManager::remove_resource(Resource &r) } else if(state>ManagedResource::LOAD_QUEUED && state=next_unload) { unload_by_age(); @@ -224,7 +238,7 @@ void ResourceManager::unload_by_size() { unsigned unload_limit = frame-min_retain_frames; - while(get_total_data_size()>size_limit) + while(get_total_data_size_()>size_limit) { ManagedResource *best = 0; UInt64 best_impact = 0; @@ -246,7 +260,7 @@ void ResourceManager::unload_by_size() } } -UInt64 ResourceManager::get_total_data_size() const +UInt64 ResourceManager::get_total_data_size_() const { UInt64 total = 0; for(ResourceMap::const_iterator i=resources.begin(); i!=resources.end(); ++i) @@ -255,6 +269,12 @@ UInt64 ResourceManager::get_total_data_size() const return total; } +UInt64 ResourceManager::get_total_data_size() const +{ + MutexLock lock(map_mutex); + return get_total_data_size_(); +} + bool ResourceManager::age_order(ManagedResource *mr1, ManagedResource *mr2) { return mr1->last_used>mr2->last_used; diff --git a/source/resourcemanager.h b/source/resourcemanager.h index 399d479a..9378d920 100644 --- a/source/resourcemanager.h +++ b/source/resourcemanager.h @@ -114,6 +114,7 @@ private: LoadingPolicy policy; bool async_loads; + mutable Mutex map_mutex; ResourceMap resources; LoadQueue queue; UInt64 size_limit; @@ -134,7 +135,11 @@ public: void set_max_retain_frames(unsigned); void add_resource(Resource &); - void *get_data_for_resource(const Resource &); +private: + const ManagedResource &get_managed_resource(const Resource &) const; + ManagedResource &get_managed_resource(const Resource &); +public: + void *get_data_for_resource(const Resource &r) { return &get_managed_resource(r); } void set_resource_location(Resource &, DataFile::Collection &, const std::string &); void set_resource_location(Resource &, const ResourceLocation &); const ResourceLocation *get_resource_location(const Resource &) const; @@ -151,6 +156,7 @@ private: void dispatch_work(); void unload_by_age(); void unload_by_size(); + UInt64 get_total_data_size_() const; public: UInt64 get_total_data_size() const;