# HG changeset patch # User Sebastien Jodogne # Date 1478691838 -3600 # Node ID 70d1fe6d63098feead78f8ff0952c6ddd5b23529 # Parent 3cde3e806abea386c6811871e741b4ad6379d991 Avoid hard crash if not enough memory diff -r 3cde3e806abe -r 70d1fe6d6309 Plugin/Cache/CacheManager.cpp --- a/Plugin/Cache/CacheManager.cpp Wed Nov 09 12:20:01 2016 +0100 +++ b/Plugin/Cache/CacheManager.cpp Wed Nov 09 12:43:58 2016 +0100 @@ -126,6 +126,7 @@ struct CacheManager::PImpl { + OrthancPluginContext* context_; Orthanc::SQLite::Connection& db_; Orthanc::FilesystemStorage& storage_; @@ -134,8 +135,10 @@ BundleQuota defaultQuota_; BundleQuotas quotas_; - PImpl(Orthanc::SQLite::Connection& db, + PImpl(OrthancPluginContext* context, + Orthanc::SQLite::Connection& db, Orthanc::FilesystemStorage& storage) : + context_(context), db_(db), storage_(storage), sanityCheck_(false) @@ -278,15 +281,22 @@ - CacheManager::CacheManager(Orthanc::SQLite::Connection& db, + CacheManager::CacheManager(OrthancPluginContext* context, + Orthanc::SQLite::Connection& db, Orthanc::FilesystemStorage& storage) : - pimpl_(new PImpl(db, storage)) + pimpl_(new PImpl(context, db, storage)) { Open(); ReadBundleStatistics(); } + OrthancPluginContext* CacheManager::GetPluginContext() const + { + return pimpl_->context_; + } + + void CacheManager::SetSanityCheckEnabled(bool enabled) { pimpl_->sanityCheck_ = enabled; diff -r 3cde3e806abe -r 70d1fe6d6309 Plugin/Cache/CacheManager.h --- a/Plugin/Cache/CacheManager.h Wed Nov 09 12:20:01 2016 +0100 +++ b/Plugin/Cache/CacheManager.h Wed Nov 09 12:43:58 2016 +0100 @@ -23,6 +23,8 @@ #include "../../Orthanc/Core/SQLite/Connection.h" #include "../../Orthanc/Core/FileStorage/FilesystemStorage.h" +#include + namespace OrthancPlugins { enum CacheProperty @@ -69,9 +71,12 @@ public: - CacheManager(Orthanc::SQLite::Connection& db, + CacheManager(OrthancPluginContext* context, + Orthanc::SQLite::Connection& db, Orthanc::FilesystemStorage& storage); + OrthancPluginContext* GetPluginContext() const; + void SetSanityCheckEnabled(bool enabled); void Clear(); diff -r 3cde3e806abe -r 70d1fe6d6309 Plugin/Cache/CacheScheduler.cpp --- a/Plugin/Cache/CacheScheduler.cpp Wed Nov 09 12:20:01 2016 +0100 +++ b/Plugin/Cache/CacheScheduler.cpp Wed Nov 09 12:43:58 2016 +0100 @@ -112,52 +112,65 @@ { std::auto_ptr prefetch(that->queue_.Dequeue(500)); - if (prefetch.get() != NULL) + try { + if (prefetch.get() != NULL) { - boost::mutex::scoped_lock lock(that->invalidatedMutex_); - that->invalidated_ = false; - that->prefetching_ = prefetch->GetValue(); - } + { + boost::mutex::scoped_lock lock(that->invalidatedMutex_); + that->invalidated_ = false; + that->prefetching_ = prefetch->GetValue(); + } + + { + boost::mutex::scoped_lock lock(that->cacheMutex_); + if (that->cache_.IsCached(that->bundleIndex_, prefetch->GetValue())) + { + // This item is already cached + continue; + } + } + + std::string content; - { - boost::mutex::scoped_lock lock(that->cacheMutex_); - if (that->cache_.IsCached(that->bundleIndex_, prefetch->GetValue())) + try + { + if (!that->factory_.Create(content, prefetch->GetValue())) + { + // The factory cannot generate this item + continue; + } + } + catch (...) { - // This item is already cached + // Exception continue; } + + { + boost::mutex::scoped_lock lock(that->invalidatedMutex_); + if (that->invalidated_) + { + // This item has been invalidated + continue; + } + + { + boost::mutex::scoped_lock lock2(that->cacheMutex_); + that->cache_.Store(that->bundleIndex_, prefetch->GetValue(), content); + } + } } - - std::string content; - - try - { - if (!that->factory_.Create(content, prefetch->GetValue())) - { - // The factory cannot generate this item - continue; - } - } - catch (...) - { - // Exception - continue; - } - - { - boost::mutex::scoped_lock lock(that->invalidatedMutex_); - if (that->invalidated_) - { - // This item has been invalidated - continue; - } - - { - boost::mutex::scoped_lock lock2(that->cacheMutex_); - that->cache_.Store(that->bundleIndex_, prefetch->GetValue(), content); - } - } + } + catch (std::bad_alloc&) + { + OrthancPluginLogError(that->cache_.GetPluginContext(), + "Not enough memory for the prefetcher of the Web viewer to work"); + } + catch (...) + { + OrthancPluginLogError(that->cache_.GetPluginContext(), + "Unhandled native exception inside the prefetcher of the Web viewer"); } } } diff -r 3cde3e806abe -r 70d1fe6d6309 Plugin/Cache/CacheScheduler.h --- a/Plugin/Cache/CacheScheduler.h Wed Nov 09 12:20:01 2016 +0100 +++ b/Plugin/Cache/CacheScheduler.h Wed Nov 09 12:43:58 2016 +0100 @@ -39,8 +39,7 @@ typedef std::map BundleSchedulers; - size_t maxPrefetchSize_; - + size_t maxPrefetchSize_; boost::mutex cacheMutex_; boost::mutex factoryMutex_; boost::recursive_mutex policyMutex_; diff -r 3cde3e806abe -r 70d1fe6d6309 Plugin/Plugin.cpp --- a/Plugin/Plugin.cpp Wed Nov 09 12:20:01 2016 +0100 +++ b/Plugin/Plugin.cpp Wed Nov 09 12:43:58 2016 +0100 @@ -96,7 +96,7 @@ boost::filesystem::path p(path); db_.Open((p / "cache.db").string()); - cache_.reset(new OrthancPlugins::CacheManager(db_, storage_)); + cache_.reset(new OrthancPlugins::CacheManager(context_, db_, storage_)); //cache_->SetSanityCheckEnabled(true); // For debug scheduler_.reset(new OrthancPlugins::CacheScheduler(*cache_, 100)); diff -r 3cde3e806abe -r 70d1fe6d6309 UnitTestsSources/UnitTestsMain.cpp --- a/UnitTestsSources/UnitTestsMain.cpp Wed Nov 09 12:20:01 2016 +0100 +++ b/UnitTestsSources/UnitTestsMain.cpp Wed Nov 09 12:43:58 2016 +0100 @@ -51,7 +51,7 @@ db_.reset(new Orthanc::SQLite::Connection()); db_->Open("UnitTestsResults/cache.db"); - cache_.reset(new CacheManager(*db_, *storage_)); + cache_.reset(new CacheManager(NULL, *db_, *storage_)); cache_->SetSanityCheckEnabled(true); }