From 261170cc5b6661106877dc2611dab281f4d91348 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Sat, 3 May 2014 22:04:16 +0200 Subject: Revamped DomDocumentCache with regard to thread safety * DomDocumentCache::item class now is _finalized_ by default and doesn't perform document instantiation, just lifetime management ** xercesc::DOMDocument is instantiated inside the external function implementations and committed to the document cache for conversion to a xalan document * added mutex with scoped lock to prevent concurrent write access to the std::unordered_map contained withing DomDocumentCache * functionality of the _get_ member method was split into _get_ and _create_ ** added typedef for std::pair specialization type "optional_item" that functions as the return value of _create_ and _get_ * "locator->getSystemId()" was leaking memory as xerces doesn't manage the lifetime of the returned heap-allocated char array ** analog to XMLCh* strings ** transformed XercesStringGuard into template class to be instantiated on either XMLCh or char --- src/support/dom/document_cache.cc | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src/support/dom/document_cache.cc') diff --git a/src/support/dom/document_cache.cc b/src/support/dom/document_cache.cc index 1573af8..c4c57d3 100644 --- a/src/support/dom/document_cache.cc +++ b/src/support/dom/document_cache.cc @@ -5,23 +5,33 @@ namespace InputXSLT { DomDocumentCache::DomDocumentCache(): + write_mutex_(), map_() { } -DomDocumentCache::item* DomDocumentCache::get(const std::string& key) { +DomDocumentCache::optional_item DomDocumentCache::get(const std::string& key) { auto itemIter = this->map_.find(key); if ( itemIter == this->map_.end() ) { - auto result = this->map_.emplace( - std::make_pair(key, std::unique_ptr(new item("content"))) - ); - - if ( result.second ) { - return (*(result.first)).second.get(); - } else { - throw std::out_of_range("failed to instantiate DomDocumentCache"); - } + return optional_item(false, nullptr); } else { - return (*itemIter).second.get(); + return optional_item(true, (*itemIter).second.get()); + } +} + +DomDocumentCache::optional_item DomDocumentCache::create( + const std::string& key, + xercesc::DOMDocument* document +) { + std::lock_guard guard(this->write_mutex_); + + auto result = this->map_.emplace( + std::make_pair(key, std::unique_ptr(new item(document))) + ); + + if ( result.second ) { + return optional_item(true, (*(result.first)).second.get()); + } else { + return optional_item(false, nullptr); } } -- cgit v1.2.3