diff options
Diffstat (limited to 'filter/source/config/cache/basecontainer.cxx')
-rw-r--r-- | filter/source/config/cache/basecontainer.cxx | 170 |
1 files changed, 55 insertions, 115 deletions
diff --git a/filter/source/config/cache/basecontainer.cxx b/filter/source/config/cache/basecontainer.cxx index 97e7b7f22bea..fe05d7f5ba2b 100644 --- a/filter/source/config/cache/basecontainer.cxx +++ b/filter/source/config/cache/basecontainer.cxx @@ -21,20 +21,16 @@ #include "basecontainer.hxx" #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> -#include <com/sun/star/document/FilterConfigRefresh.hpp> #include <com/sun/star/uno/Type.h> #include <comphelper/enumhelper.hxx> #include <comphelper/sequence.hxx> #include <cppuhelper/supportsservice.hxx> #include <osl/diagnose.h> -#define LOAD_IMPLICIT - namespace filter::config{ BaseContainer::BaseContainer() : m_eType() - , m_lListener (m_aMutex) { GetTheFilterCache().load(FilterCache::E_CONTAINS_STANDARD); } @@ -45,28 +41,22 @@ BaseContainer::~BaseContainer() } -void BaseContainer::init(const css::uno::Reference< css::uno::XComponentContext >& rxContext , - const OUString& sImplementationName, +void BaseContainer::init(const OUString& sImplementationName, const css::uno::Sequence< OUString >& lServiceNames , FilterCache::EItemType eType ) { // SAFE -> - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); m_sImplementationName = sImplementationName; m_lServiceNames = lServiceNames ; m_eType = eType ; - m_xRefreshBroadcaster = css::document::FilterConfigRefresh::create(rxContext); // <- SAFE } -void BaseContainer::impl_loadOnDemand() +void BaseContainer::impl_loadOnDemand(std::unique_lock<std::mutex>& /*rGuard*/) { -#ifdef LOAD_IMPLICIT - // SAFE -> - osl::MutexGuard aLock(m_aMutex); - // A generic container needs all items of a set of our cache! // Of course it can block for a while, till the cache is really filled. // Note: don't load all sets supported by the cache here! @@ -92,33 +82,25 @@ void BaseContainer::impl_loadOnDemand() } GetTheFilterCache().load(eRequiredState); - // <- SAFE -#endif } -void BaseContainer::impl_initFlushMode() +void BaseContainer::impl_initFlushMode(std::unique_lock<std::mutex>& /*rGuard*/) { - // SAFE -> - osl::MutexGuard aLock(m_aMutex); if (!m_pFlushCache) m_pFlushCache = GetTheFilterCache().clone(); if (!m_pFlushCache) throw css::uno::RuntimeException( "Can not create write copy of internal used cache on demand.", - static_cast< OWeakObject* >(this)); - // <- SAFE + getXWeak()); } -FilterCache* BaseContainer::impl_getWorkingCache() const +FilterCache* BaseContainer::impl_getWorkingCache(std::unique_lock<std::mutex>& /*rGuard*/) const { - // SAFE -> - osl::MutexGuard aLock(m_aMutex); if (m_pFlushCache) return m_pFlushCache.get(); else return &GetTheFilterCache(); - // <- SAFE } @@ -157,15 +139,15 @@ void SAL_CALL BaseContainer::insertByName(const OUString& sItem , throw css::lang::IllegalArgumentException(ex.Message, static_cast< css::container::XNameContainer* >(this), 2); } - impl_loadOnDemand(); - // SAFE -> ---------------------------------- - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); // create write copy of used cache on demand ... - impl_initFlushMode(); + impl_initFlushMode(aLock); - FilterCache* pCache = impl_getWorkingCache(); + FilterCache* pCache = impl_getWorkingCache(aLock); if (pCache->hasItem(m_eType, sItem)) throw css::container::ElementExistException(OUString(), static_cast< css::container::XNameContainer* >(this)); pCache->setItem(m_eType, sItem, aItem); @@ -175,15 +157,15 @@ void SAL_CALL BaseContainer::insertByName(const OUString& sItem , void SAL_CALL BaseContainer::removeByName(const OUString& sItem) { - impl_loadOnDemand(); - // SAFE -> ---------------------------------- - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); // create write copy of used cache on demand ... - impl_initFlushMode(); + impl_initFlushMode(aLock); - FilterCache* pCache = impl_getWorkingCache(); + FilterCache* pCache = impl_getWorkingCache(aLock); pCache->removeItem(m_eType, sItem); // throw exceptions automatically // <- SAFE ---------------------------------- } @@ -207,15 +189,15 @@ void SAL_CALL BaseContainer::replaceByName(const OUString& sItem , throw css::lang::IllegalArgumentException(ex.Message, static_cast< css::container::XNameContainer* >(this), 2); } - impl_loadOnDemand(); - // SAFE -> ---------------------------------- - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); // create write copy of used cache on demand ... - impl_initFlushMode(); + impl_initFlushMode(aLock); - FilterCache* pCache = impl_getWorkingCache(); + FilterCache* pCache = impl_getWorkingCache(aLock); if (!pCache->hasItem(m_eType, sItem)) throw css::container::NoSuchElementException(OUString(), static_cast< css::container::XNameContainer* >(this)); pCache->setItem(m_eType, sItem, aItem); @@ -231,17 +213,15 @@ css::uno::Any SAL_CALL BaseContainer::getByName(const OUString& sItem) css::uno::Any aValue; - impl_loadOnDemand(); - // SAFE -> - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); - CacheItem aItem; try { - FilterCache* pCache = impl_getWorkingCache(); - aItem = pCache->getItem(m_eType, sItem); - pCache->addStatePropsToItem(m_eType, sItem, aItem); // add implicit props "Finalized"/"Mandatory" + FilterCache* pCache = impl_getWorkingCache(aLock); + aValue = pCache->getItemWithStateProps(m_eType, sItem); } catch(const css::container::NoSuchElementException&) { @@ -250,10 +230,8 @@ css::uno::Any SAL_CALL BaseContainer::getByName(const OUString& sItem) catch(const css::uno::Exception&) { // TODO invalid cache!? How should it be handled right? - aItem.clear(); } - aValue <<= aItem.getAsPackedPropertyValueList(); // <- SAFE return aValue; @@ -264,14 +242,14 @@ css::uno::Sequence< OUString > SAL_CALL BaseContainer::getElementNames() { css::uno::Sequence< OUString > lNames; - impl_loadOnDemand(); - // SAFE -> - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); try { - FilterCache* pCache = impl_getWorkingCache(); + FilterCache* pCache = impl_getWorkingCache(aLock); std::vector<OUString> lKeys = pCache->getItemNames(m_eType); lNames = comphelper::containerToSequence(lKeys); } @@ -291,14 +269,14 @@ sal_Bool SAL_CALL BaseContainer::hasByName(const OUString& sItem) { bool bHasOne = false; - impl_loadOnDemand(); - // SAFE -> - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); try { - FilterCache* pCache = impl_getWorkingCache(); + FilterCache* pCache = impl_getWorkingCache(aLock); bHasOne = pCache->hasItem(m_eType, sItem); } catch(const css::uno::Exception&) @@ -325,14 +303,14 @@ sal_Bool SAL_CALL BaseContainer::hasElements() { bool bHasSome = false; - impl_loadOnDemand(); - // SAFE -> - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); try { - FilterCache* pCache = impl_getWorkingCache(); + FilterCache* pCache = impl_getWorkingCache(aLock); bHasSome = pCache->hasItems(m_eType); } catch(const css::uno::Exception&) @@ -351,7 +329,7 @@ css::uno::Reference< css::container::XEnumeration > SAL_CALL BaseContainer::crea { OSL_FAIL("not pure virtual ... but not really implemented .-)"); - return new ::comphelper::OEnumerationByName(this, css::uno::Sequence< OUString >()); + return new ::comphelper::OEnumerationByName(this, {}); } @@ -359,21 +337,17 @@ css::uno::Reference< css::container::XEnumeration > SAL_CALL BaseContainer::crea { std::vector<OUString> lKeys; - impl_loadOnDemand(); - // SAFE -> - osl::MutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); + + impl_loadOnDemand(aLock); try { - // convert the given properties first to our internal representation - CacheItem lProps; - lProps << lProperties; - // search the key names of all items, where its properties match // the given ones in its minimum - FilterCache* pCache = impl_getWorkingCache(); - lKeys = pCache->getMatchingItemsByProps(m_eType, lProps); + FilterCache* pCache = impl_getWorkingCache(aLock); + lKeys = pCache->getMatchingItemsByProps(m_eType, std::span<const css::beans::NamedValue>( lProperties.getConstArray(), lProperties.getLength() )); } catch(const css::uno::Exception&) { @@ -394,20 +368,19 @@ css::uno::Reference< css::container::XEnumeration > SAL_CALL BaseContainer::crea Further its easier to work directly with the return value instead of checking of NULL returns! */ - css::uno::Sequence< OUString > lSubSet = comphelper::containerToSequence(lKeys); - return new ::comphelper::OEnumerationByName(this, lSubSet); + return new ::comphelper::OEnumerationByName(this, std::move(lKeys)); } void SAL_CALL BaseContainer::flush() { // SAFE -> - osl::ClearableMutexGuard aLock(m_aMutex); + std::unique_lock aLock(m_aMutex); if (!m_pFlushCache) throw css::lang::WrappedTargetRuntimeException( "Can not guarantee cache consistency. Special flush container does not exists!", - static_cast< OWeakObject* >(this), + getXWeak(), css::uno::Any()); try @@ -429,63 +402,30 @@ void SAL_CALL BaseContainer::flush() // later again ... throw css::lang::WrappedTargetRuntimeException( "Flush rejected by internal container.", - static_cast< OWeakObject* >(this), - css::uno::makeAny(ex)); + getXWeak(), + css::uno::Any(ex)); } m_pFlushCache.reset(); - css::uno::Reference< css::util::XRefreshable > xRefreshBroadcaster = m_xRefreshBroadcaster; - - aLock.clear(); - // <- SAFE - - if (xRefreshBroadcaster.is()) - xRefreshBroadcaster->refresh(); - - // notify listener outside the lock! - // The used listener helper lives if we live - // and is threadsafe by itself. - // Further it's not a good idea to hold the own lock - // if an outside object is called :-) css::lang::EventObject aSource (static_cast< css::util::XFlushable* >(this)); - comphelper::OInterfaceContainerHelper2* pContainer = m_lListener.getContainer(cppu::UnoType<css::util::XFlushListener>::get()); - if (!pContainer) - return; + m_lListener.notifyEach( aLock, &css::util::XFlushListener::flushed, aSource); - comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer); - while (pIterator.hasMoreElements()) - { - try - { - // ... this pointer can be interesting to find out, where will be called as listener - // Don't optimize it to a direct iterator cast :-) - css::util::XFlushListener* pListener = static_cast<css::util::XFlushListener*>(pIterator.next()); - pListener->flushed(aSource); - } - catch(const css::uno::Exception&) - { - // ignore any "damaged" flush listener! - // May its remote reference is broken ... - pIterator.remove(); - } - } + // <- SAFE } void SAL_CALL BaseContainer::addFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener) { - // no locks necessary - // used helper lives if we live and is threadsafe by itself ... - m_lListener.addInterface(cppu::UnoType<css::util::XFlushListener>::get(), xListener); + std::unique_lock g(m_aMutex); + m_lListener.addInterface(g, xListener); } void SAL_CALL BaseContainer::removeFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener) { - // no locks necessary - // used helper lives if we live and is threadsafe by itself ... - m_lListener.removeInterface(cppu::UnoType<css::util::XFlushListener>::get(), xListener); + std::unique_lock g(m_aMutex); + m_lListener.removeInterface(g, xListener); } } // namespace filter::config |