comphelper/source/misc/configuration.cxx | 104 +++++++------------------------ include/comphelper/configuration.hxx | 2 2 files changed, 26 insertions(+), 80 deletions(-)
New commits: commit df79a29ea20fb698d650be45a48c607f54476dea Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Mon Dec 26 12:27:27 2022 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Dec 27 18:09:48 2022 +0000 Revert "optimize ConfigurationProperty::get()" (7.4 only) This reverts commit 7df433cdc33b4d6ba38eafad9282d015571433ef in libreoffice-7-4 only. See https://gerrit.libreoffice.org/c/core/+/144821 it seems it introduced https://crashreport.libreoffice.org/stats/signature/void%20rtl::str::release%3C_rtl_uString%3E(_rtl_uString*) which, at the moment, is the most reported crash in https://crashreport.libreoffice.org/stats/version/7.4.3.2 I sent Luboš an email about this more than a week ago but I didn't get any answer so let's revert it for the time being This commit also reverts b4b63d0c46979ad6b6aae5d6a4ea6672ea248e10 "try to fix some shutdown crashes" which was a blind fix. Unfortunately it didn't fix the issue since this commit is included in LibreOffice 7.4.3.2 Finally, adapt code to make loplugin:stringviewparam happy with getPropertyValue Change-Id: I870c4ab0c0d27ae4c9dd94c3abcc2c5eb17ab09d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144804 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/comphelper/source/misc/configuration.cxx b/comphelper/source/misc/configuration.cxx index 1d6517fbb26d..59631dbccd83 100644 --- a/comphelper/source/misc/configuration.cxx +++ b/comphelper/source/misc/configuration.cxx @@ -10,11 +10,11 @@ #include <sal/config.h> #include <cassert> +#include <map> +#include <memory> #include <mutex> #include <string_view> -#include <unordered_map> -#include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/configuration/ReadOnlyAccess.hpp> #include <com/sun/star/configuration/ReadWriteAccess.hpp> @@ -27,12 +27,9 @@ #include <com/sun/star/lang/XLocalizable.hpp> #include <com/sun/star/uno/Any.hxx> #include <com/sun/star/uno/Reference.hxx> -#include <com/sun/star/util/XChangesListener.hpp> -#include <com/sun/star/util/XChangesNotifier.hpp> #include <comphelper/solarmutex.hxx> #include <comphelper/configuration.hxx> #include <comphelper/configurationlistener.hxx> -#include <cppuhelper/implbase.hxx> #include <rtl/ustring.hxx> #include <sal/log.hxx> #include <i18nlangtag/languagetag.hxx> @@ -109,70 +106,12 @@ comphelper::detail::ConfigurationWrapper::get() return WRAPPER; } -namespace -{ -std::mutex gMutex; -std::unordered_map<OUString, css::uno::Any> gPropertyCache; -css::uno::Reference< css::util::XChangesNotifier > gNotifier; -css::uno::Reference< css::util::XChangesListener > gListener; - -class ConfigurationChangesListener - : public ::cppu::WeakImplHelper<css::util::XChangesListener> -{ -public: - ConfigurationChangesListener() - {} - // util::XChangesListener - virtual void SAL_CALL changesOccurred( const css::util::ChangesEvent& ) override - { - std::scoped_lock aGuard(gMutex); - gPropertyCache.clear(); - } - virtual void SAL_CALL disposing(const css::lang::EventObject&) override - { - std::scoped_lock aGuard(gMutex); - gPropertyCache.clear(); - } -}; - -} // namespace - comphelper::detail::ConfigurationWrapper::ConfigurationWrapper(): context_(comphelper::getProcessComponentContext()), access_(css::configuration::ReadWriteAccess::create(context_, "*")) -{ - // Set up a configuration notifier to invalidate the cache as needed. - try - { - css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider( - css::configuration::theDefaultProvider::get( context_ ) ); - - // set root path - css::uno::Sequence< css::uno::Any > params { - css::uno::Any( css::beans::NamedValue{ "nodepath", css::uno::Any( OUString("/"))} ), - css::uno::Any( css::beans::NamedValue{ "locale", css::uno::Any( OUString("*"))} ) }; - - css::uno::Reference< css::uno::XInterface > xCfg - = xConfigProvider->createInstanceWithArguments(u"com.sun.star.configuration.ConfigurationAccess", - params); - - gNotifier = css::uno::Reference< css::util::XChangesNotifier >(xCfg, css::uno::UNO_QUERY); - assert(gNotifier.is()); - gListener = css::uno::Reference< ConfigurationChangesListener >(new ConfigurationChangesListener()); - gNotifier->addChangesListener(gListener); - } - catch(const css::uno::Exception&) - { - assert(false); - } -} +{} -comphelper::detail::ConfigurationWrapper::~ConfigurationWrapper() -{ - gPropertyCache.clear(); - gNotifier.clear(); - gListener.clear(); -} +comphelper::detail::ConfigurationWrapper::~ConfigurationWrapper() {} bool comphelper::detail::ConfigurationWrapper::isReadOnly(OUString const & path) const @@ -183,24 +122,31 @@ bool comphelper::detail::ConfigurationWrapper::isReadOnly(OUString const & path) != 0; } -css::uno::Any comphelper::detail::ConfigurationWrapper::getPropertyValue(OUString const& path) const +css::uno::Any comphelper::detail::ConfigurationWrapper::getPropertyValue(std::u16string_view path) const { - std::scoped_lock aGuard(gMutex); // Cache the configuration access, since some of the keys are used in hot code. - auto it = gPropertyCache.find(path); - if( it != gPropertyCache.end()) - return it->second; + // Note that this cache is only used by the officecfg:: auto-generated code, using it for anything + // else would be unwise because the cache could end up containing stale entries. + static std::mutex gMutex; + static std::map<OUString, css::uno::Reference< css::container::XNameAccess >> gAccessMap; - sal_Int32 idx = path.lastIndexOf("/"); + sal_Int32 idx = path.rfind('/'); assert(idx!=-1); - OUString parentPath = path.copy(0, idx); - OUString childName = path.copy(idx+1); - - css::uno::Reference<css::container::XNameAccess> access( - access_->getByHierarchicalName(parentPath), css::uno::UNO_QUERY_THROW); - css::uno::Any property = access->getByName(childName); - gPropertyCache.emplace(path, property); - return property; + OUString parentPath(path.substr(0, idx)); + OUString childName(path.substr(idx+1)); + + std::scoped_lock aGuard(gMutex); + + // check cache + auto it = gAccessMap.find(parentPath); + if (it == gAccessMap.end()) + { + // not in the cache, look it up + css::uno::Reference<css::container::XNameAccess> access( + access_->getByHierarchicalName(parentPath), css::uno::UNO_QUERY_THROW); + it = gAccessMap.emplace(parentPath, access).first; + } + return it->second->getByName(childName); } void comphelper::detail::ConfigurationWrapper::setPropertyValue( diff --git a/include/comphelper/configuration.hxx b/include/comphelper/configuration.hxx index 3b8f8f1f7e93..222b9d5af124 100644 --- a/include/comphelper/configuration.hxx +++ b/include/comphelper/configuration.hxx @@ -87,7 +87,7 @@ public: bool isReadOnly(OUString const & path) const; - css::uno::Any getPropertyValue(OUString const & path) const; + css::uno::Any getPropertyValue(std::u16string_view path) const; static void setPropertyValue( std::shared_ptr< ConfigurationChanges > const & batch,