From 751a5ad9c4e75fd1019bd4bca940d8a9e73f171a Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Tue, 30 Jul 2019 15:30:39 +0200 Subject: unordf: restore thread safety (regression from f2c513e686536dc308609c56fa9354d4d10b072c) Change-Id: I620d726555172fbaec3d468bcf21c0c1101cdc70 Reviewed-on: https://gerrit.libreoffice.org/76601 Tested-by: Jenkins Reviewed-by: Michael Stahl --- unoxml/source/rdf/librdf_repository.cxx | 65 +++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 23 deletions(-) (limited to 'unoxml') diff --git a/unoxml/source/rdf/librdf_repository.cxx b/unoxml/source/rdf/librdf_repository.cxx index 26f4a950518c..e775be583bf0 100644 --- a/unoxml/source/rdf/librdf_repository.cxx +++ b/unoxml/source/rdf/librdf_repository.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -243,12 +244,12 @@ public: Statement const& i_rStatement); static std::shared_ptr extractResource_NoLock( const uno::Reference< rdf::XResource > & i_xResource); - static void extractResourceToCacheKey( + static void extractResourceToCacheKey_NoLock( const uno::Reference< rdf::XResource > & i_xResource, OUStringBuffer& rBuf); static std::shared_ptr extractNode_NoLock( const uno::Reference< rdf::XNode > & i_xNode); - static void extractNodeToCacheKey( + static void extractNodeToCacheKey_NoLock( const uno::Reference< rdf::XNode > & i_xNode, OUStringBuffer& rBuffer); static Statement extractStatement_NoLock( @@ -550,7 +551,7 @@ public: private: std::vector m_vStatements; - int m_nIndex = 0; + std::atomic m_nIndex = 0; }; @@ -558,16 +559,19 @@ private: sal_Bool SAL_CALL librdf_GraphResult2::hasMoreElements() { - return m_nIndex < static_cast(m_vStatements.size()); + return m_nIndex < m_vStatements.size(); } css::uno::Any SAL_CALL librdf_GraphResult2::nextElement() { - if (m_nIndex >= static_cast(m_vStatements.size())) + std::size_t const n = m_nIndex++; + if (m_vStatements.size() < n) + { + m_nIndex = m_vStatements.size(); // avoid overflow throw container::NoSuchElementException(); - m_nIndex++; - return uno::makeAny(m_vStatements[m_nIndex-1]); + } + return uno::makeAny(m_vStatements[n]); } /** result of tuple queries ("SELECT"). @@ -731,7 +735,7 @@ private: librdf_NamedGraph(librdf_NamedGraph const&) = delete; librdf_NamedGraph& operator=(librdf_NamedGraph const&) = delete; - static OUString createCacheKey( + static OUString createCacheKey_NoLock( const uno::Reference< rdf::XResource > & i_xSubject, const uno::Reference< rdf::XURI > & i_xPredicate, const uno::Reference< rdf::XNode > & i_xObject); @@ -741,8 +745,9 @@ private: librdf_Repository *const m_pRep; uno::Reference< rdf::XURI > const m_xName; - // Querying is rather slow, so cache the results. + /// Querying is rather slow, so cache the results. std::map> m_aStatementsCache; + ::osl::Mutex m_CacheMutex; }; @@ -784,6 +789,7 @@ void SAL_CALL librdf_NamedGraph::clear() throw lang::WrappedTargetRuntimeException( ex.Message, *this, anyEx ); } + ::osl::MutexGuard g(m_CacheMutex); m_aStatementsCache.clear(); } @@ -797,7 +803,10 @@ void SAL_CALL librdf_NamedGraph::addStatement( throw rdf::RepositoryException( "librdf_NamedGraph::addStatement: repository is gone", *this); } - m_aStatementsCache.clear(); + { + ::osl::MutexGuard g(m_CacheMutex); + m_aStatementsCache.clear(); + } m_pRep->addStatementGraph_NoLock( i_xSubject, i_xPredicate, i_xObject, m_xName); } @@ -812,22 +821,25 @@ void SAL_CALL librdf_NamedGraph::removeStatements( throw rdf::RepositoryException( "librdf_NamedGraph::removeStatements: repository is gone", *this); } - m_aStatementsCache.clear(); + { + ::osl::MutexGuard g(m_CacheMutex); + m_aStatementsCache.clear(); + } m_pRep->removeStatementsGraph_NoLock( i_xSubject, i_xPredicate, i_xObject, m_xName); } -OUString librdf_NamedGraph::createCacheKey( +OUString librdf_NamedGraph::createCacheKey_NoLock( const uno::Reference< rdf::XResource > & i_xSubject, const uno::Reference< rdf::XURI > & i_xPredicate, const uno::Reference< rdf::XNode > & i_xObject) { OUStringBuffer cacheKey(256); - librdf_TypeConverter::extractResourceToCacheKey(i_xSubject, cacheKey); + librdf_TypeConverter::extractResourceToCacheKey_NoLock(i_xSubject, cacheKey); cacheKey.append("\t"); - librdf_TypeConverter::extractResourceToCacheKey(i_xPredicate, cacheKey); + librdf_TypeConverter::extractResourceToCacheKey_NoLock(i_xPredicate, cacheKey); cacheKey.append("\t"); - librdf_TypeConverter::extractNodeToCacheKey(i_xObject, cacheKey); + librdf_TypeConverter::extractNodeToCacheKey_NoLock(i_xObject, cacheKey); return cacheKey.makeStringAndClear(); } @@ -837,10 +849,14 @@ librdf_NamedGraph::getStatements( const uno::Reference< rdf::XURI > & i_xPredicate, const uno::Reference< rdf::XNode > & i_xObject) { - OUString cacheKey = createCacheKey(i_xSubject, i_xPredicate, i_xObject); - auto it = m_aStatementsCache.find(cacheKey); - if (it != m_aStatementsCache.end()) - return new librdf_GraphResult2(it->second); + OUString cacheKey = createCacheKey_NoLock(i_xSubject, i_xPredicate, i_xObject); + { + ::osl::MutexGuard g(m_CacheMutex); + auto it = m_aStatementsCache.find(cacheKey); + if (it != m_aStatementsCache.end()) { + return new librdf_GraphResult2(it->second); + } + } uno::Reference< rdf::XRepository > xRep( m_wRep ); if (!xRep.is()) { @@ -850,7 +866,10 @@ librdf_NamedGraph::getStatements( std::vector vStatements = m_pRep->getStatementsGraph_NoLock( i_xSubject, i_xPredicate, i_xObject, m_xName); - m_aStatementsCache.emplace(cacheKey, vStatements); + { + ::osl::MutexGuard g(m_CacheMutex); + m_aStatementsCache.emplace(cacheKey, vStatements); + } return new librdf_GraphResult2(vStatements); } @@ -2130,7 +2149,7 @@ librdf_TypeConverter::extractResource_NoLock( } void -librdf_TypeConverter::extractResourceToCacheKey( +librdf_TypeConverter::extractResourceToCacheKey_NoLock( const uno::Reference< rdf::XResource > & i_xResource, OUStringBuffer& rBuffer) { if (!i_xResource.is()) { @@ -2213,7 +2232,7 @@ librdf_TypeConverter::extractNode_NoLock( // extract blank or URI or literal node - call without Mutex locked void -librdf_TypeConverter::extractNodeToCacheKey( +librdf_TypeConverter::extractNodeToCacheKey_NoLock( const uno::Reference< rdf::XNode > & i_xNode, OUStringBuffer& rBuffer) { @@ -2222,7 +2241,7 @@ librdf_TypeConverter::extractNodeToCacheKey( } uno::Reference< rdf::XResource > xResource(i_xNode, uno::UNO_QUERY); if (xResource.is()) { - return extractResourceToCacheKey(xResource, rBuffer); + return extractResourceToCacheKey_NoLock(xResource, rBuffer); } uno::Reference< rdf::XLiteral> xLiteral(i_xNode, uno::UNO_QUERY); OSL_ENSURE(xLiteral.is(), -- cgit