]> git.tdb.fi Git - libs/gl.git/blobdiff - source/resourcemanager.cpp
Pass errors from the resource loading thread to the main thread
[libs/gl.git] / source / resourcemanager.cpp
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;