]> git.tdb.fi Git - libs/gl.git/commitdiff
Make ResourceManager thread-safe
authorMikko Rasa <tdb@tdb.fi>
Fri, 4 Dec 2015 09:36:07 +0000 (11:36 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 4 Dec 2015 09:36:07 +0000 (11:36 +0200)
Since a big part of the class is loading resources asynchronously, it
makes sense that resources can also be created from another thread.

source/resourcemanager.cpp
source/resourcemanager.h

index bcc4839b6b6073cb5b356c16aa4be3c261522023..52e5866a6aa887ce536d704f528dfbc5051f06cf 100644 (file)
@@ -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<ManagedResource::LOADED)
                thread.remove_resource(managed);
+
+       MutexLock lock(map_mutex);
        remove_existing(resources, &r);
 }
 
 void ResourceManager::watch_resource(const Resource &r, ResourceWatcher &w)
 {
-       get_item(resources, &r).add_watcher(w);
+       get_managed_resource(r).add_watcher(w);
 }
 
 void ResourceManager::unwatch_resource(const Resource &r, ResourceWatcher &w)
 {
-       get_item(resources, &r).remove_watcher(w);
+       get_managed_resource(r).remove_watcher(w);
 }
 
 void ResourceManager::tick()
@@ -175,6 +188,7 @@ void ResourceManager::tick()
 
        if(do_unload)
        {
+               MutexLock lock(map_mutex);
                if(max_retain_frames && frame>=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;
index 399d479abd2111dab7de39b557846d03aa797b2c..9378d920c9671743daafddfec70def0acee39e68 100644 (file)
@@ -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;