From 508319df28270eccdfa03a880a8604549278a139 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 26 Nov 2014 11:24:12 +0200 Subject: [PATCH] Pass errors from the resource loading thread to the main thread --- source/resourcemanager.cpp | 29 +++++++++++++++++++++++++++-- source/resourcemanager.h | 12 +++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/source/resourcemanager.cpp b/source/resourcemanager.cpp index 7bf4412f..c6e3f357 100644 --- a/source/resourcemanager.cpp +++ b/source/resourcemanager.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include #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; diff --git a/source/resourcemanager.h b/source/resourcemanager.h index a1ff7aee..a2a4975d 100644 --- a/source/resourcemanager.h +++ b/source/resourcemanager.h @@ -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 error_queue; volatile bool done; public: -- 2.43.0