diff options
author | Adrian Kummerländer | 2014-05-03 22:04:16 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2014-05-03 22:04:16 +0200 |
commit | 261170cc5b6661106877dc2611dab281f4d91348 (patch) | |
tree | 8482f249c090af5ca462f7e36a4b87082185f027 /src/support/dom | |
parent | e5ed418907f09bf8905463f42a44593d51159bc9 (diff) | |
download | InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.gz InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.bz2 InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.lz InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.xz InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.tar.zst InputXSLT-261170cc5b6661106877dc2611dab281f4d91348.zip |
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
Diffstat (limited to 'src/support/dom')
-rw-r--r-- | src/support/dom/document_cache.cc | 32 | ||||
-rw-r--r-- | src/support/dom/document_cache.h | 10 | ||||
-rw-r--r-- | src/support/dom/document_cache_item.cc | 43 | ||||
-rw-r--r-- | src/support/dom/document_cache_item.h | 10 |
4 files changed, 39 insertions, 56 deletions
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<item>(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<std::mutex> guard(this->write_mutex_); + + auto result = this->map_.emplace( + std::make_pair(key, std::unique_ptr<item>(new item(document))) + ); + + if ( result.second ) { + return optional_item(true, (*(result.first)).second.get()); + } else { + return optional_item(false, nullptr); } } diff --git a/src/support/dom/document_cache.h b/src/support/dom/document_cache.h index 287a316..af99102 100644 --- a/src/support/dom/document_cache.h +++ b/src/support/dom/document_cache.h @@ -1,8 +1,11 @@ #ifndef INPUTXSLT_SRC_SUPPORT_DOM_DOCUMENT_CACHE_H_ #define INPUTXSLT_SRC_SUPPORT_DOM_DOCUMENT_CACHE_H_ -#include <unordered_map> +#include <xercesc/dom/DOMDocument.hpp> + #include <string> +#include <mutex> +#include <unordered_map> #include <memory> namespace InputXSLT { @@ -10,12 +13,15 @@ namespace InputXSLT { class DomDocumentCache { public: class item; + typedef std::pair<bool, item*> optional_item; DomDocumentCache(); - item* get(const std::string&); + optional_item get(const std::string&); + optional_item create(const std::string&, xercesc::DOMDocument*); private: + std::mutex write_mutex_; std::unordered_map<std::string, std::unique_ptr<item>> map_; }; diff --git a/src/support/dom/document_cache_item.cc b/src/support/dom/document_cache_item.cc index 8cc1c24..9798bfa 100644 --- a/src/support/dom/document_cache_item.cc +++ b/src/support/dom/document_cache_item.cc @@ -1,50 +1,23 @@ #include "support/dom/document_cache_item.h" -#include <xercesc/dom/DOMImplementation.hpp> -#include <xercesc/util/XMLString.hpp> - -#include "support/xerces_string_guard.h" - namespace InputXSLT { -DomDocumentCache::item::item(const std::string& rootNode): +DomDocumentCache::item::item(xercesc::DOMDocument* document): parser_(), dom_support_(parser_), - document_( - xercesc::DOMImplementation::getImplementation()->createDocument( - nullptr, - *XercesStringGuard(rootNode), - nullptr - ) - ), - parsed_source_() { } + document_(document), + parsed_source_( + document_, + parser_, + dom_support_ + ) { } DomDocumentCache::item::~item() { this->document_->release(); } -bool DomDocumentCache::item::isFinalized() const { - return static_cast<bool>(this->parsed_source_); -} - -xercesc::DOMDocument* DomDocumentCache::item::getXercesDocument() const { - return this->document_; -} - xalan::XalanDocument* DomDocumentCache::item::getXalanDocument() { - if ( this->parsed_source_ ) { - return this->parsed_source_->getDocument(); - } else { - this->parsed_source_.reset( - new xalan::XercesDOMWrapperParsedSource( - document_, - parser_, - dom_support_ - ) - ); - - return this->parsed_source_->getDocument(); - } + return this->parsed_source_.getDocument(); } } diff --git a/src/support/dom/document_cache_item.h b/src/support/dom/document_cache_item.h index 1f7152b..13fddfc 100644 --- a/src/support/dom/document_cache_item.h +++ b/src/support/dom/document_cache_item.h @@ -7,9 +7,6 @@ #include <xercesc/dom/DOMDocument.hpp> -#include <string> -#include <memory> - #include "common.h" #include "document_cache.h" @@ -19,21 +16,18 @@ class DomDocumentCache::item { public: ~item(); - bool isFinalized() const; - - xercesc::DOMDocument* getXercesDocument() const; xalan::XalanDocument* getXalanDocument(); protected: friend DomDocumentCache; - item(const std::string&); + item(xercesc::DOMDocument*); private: xalan::XercesParserLiaison parser_; xalan::XercesDOMSupport dom_support_; xercesc::DOMDocument* const document_; - std::unique_ptr<xalan::XercesDOMWrapperParsedSource> parsed_source_; + xalan::XercesDOMWrapperParsedSource parsed_source_; }; |