]> git.tdb.fi Git - libs/gl.git/commitdiff
Pass errors from the resource loading thread to the main thread
authorMikko Rasa <tdb@tdb.fi>
Wed, 26 Nov 2014 09:24:12 +0000 (11:24 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 26 Nov 2014 09:24:12 +0000 (11:24 +0200)
source/resourcemanager.cpp
source/resourcemanager.h

index 7bf4412f41c7bdbc7d372ab08aba0d9280f1cdfc..c6e3f357b9ce67b6f72fef04f30b5ff5e96483ab 100644 (file)
@@ -1,4 +1,7 @@
 #include <algorithm>
+#include <typeinfo>
+#include <msp/debug/demangle.h>
+#include <msp/strings/format.h>
 #include <msp/time/utils.h>
 #include "resourcemanager.h"
 #include "resourcewatcher.h"
@@ -8,6 +11,11 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
+resource_load_error::resource_load_error(const string &name, const exception &exc):
+       runtime_error(format("%s: %s: %s", name, Debug::demangle(typeid(exc).name()), exc.what()))
+{ }
+
+
 ResourceManager::ResourceManager():
        policy(LOAD_ON_DEMAND),
        async_loads(true),
@@ -329,7 +337,16 @@ void ResourceManager::LoadingThread::main()
 
                if(ManagedResource *managed = front(async_queue))
                {
-                       managed->process(false);
+                       try
+                       {
+                               managed->process(false);
+                       }
+                       catch(const exception &e)
+                       {
+                               MutexLock lock(queue_mutex);
+                               error_queue.push_back(resource_load_error(managed->name, e));
+                               managed->state = ManagedResource::LOAD_ERROR;
+                       }
 
                        MutexLock lock(queue_mutex);
                        sync_queue.splice(sync_queue.end(), async_queue, async_queue.begin());
@@ -398,6 +415,14 @@ bool ResourceManager::LoadingThread::sync()
 {
        {
                MutexLock lock(queue_mutex);
+
+               if(!error_queue.empty())
+               {
+                       resource_load_error err = error_queue.front();
+                       error_queue.pop_front();
+                       throw err;
+               }
+
                unsigned async_size = async_queue.size();
                if(async_size==0 && size==capacity)
                        ++capacity;
@@ -408,7 +433,7 @@ bool ResourceManager::LoadingThread::sync()
        bool any_finished = false;
        while(ManagedResource *managed = front(sync_queue))
        {
-               if(managed->process(true))
+               if(managed->state==ManagedResource::LOAD_ERROR || managed->process(true))
                {
                        managed->finish_loading();
                        any_finished = true;
index a1ff7aee2fc32adda60d12b0a63166c635e81822..a2a4975db5185eaf3eadf7348e995f9a0b4ca5b7 100644 (file)
@@ -13,6 +13,14 @@ namespace GL {
 
 class ResourceWatcher;
 
+class resource_load_error: public std::runtime_error
+{
+public:
+       resource_load_error(const std::string &, const std::exception &);
+       virtual ~resource_load_error() throw() { }
+};
+
+
 class ResourceManager
 {
 public:
@@ -32,7 +40,8 @@ private:
                        LOAD_QUEUED,
                        LOADING,
                        LOAD_FINISHED,
-                       LOADED
+                       LOADED,
+                       LOAD_ERROR
                };
 
                Resource *resource;
@@ -68,6 +77,7 @@ private:
                LoadQueue sync_queue;
                unsigned capacity;
                unsigned size;
+               std::list<resource_load_error> error_queue;
                volatile bool done;
 
        public: