comphelper/source/misc/configuration.cxx |  107 ++++++++-----------------------
 include/comphelper/configuration.hxx     |   22 +-----
 2 files changed, 32 insertions(+), 97 deletions(-)

New commits:
commit 7b46c77366fb3effd2de9bf5ba11ebd3c064974a
Author:     Xisco Fauli <[email protected]>
AuthorDate: Wed Jan 31 10:18:29 2024 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Wed Jan 31 12:53:30 2024 +0100

    tdf#157042: Revert "re-apply "optimize ConfigurationProperty::get()""
    
    This reverts commit 3a4a00a51acca8f9b5e775547abff0c4dc9144d7.
    
    It causes 
https://crashreport.libreoffice.org/stats/signature/void%20rtl::str::release%3C_rtl_uString%3E(_rtl_uString*)
    Looking at other reports of the same crash,
    the issue started in 7.4 branch with 
7df433cdc33b4d6ba38eafad9282d015571433ef
    "optimize ConfigurationProperty::get()" which was later reverted with
    df79a29ea20fb698d650be45a48c607f54476dea
    "Revert "optimize ConfigurationProperty::get()" (7.4 only)"
    In 7.5 branch Noel tried a different fix with 
203ad037ccb9fdebffea4f622229ded90635eb8b
    "try to fix shutdown crashes in ConfigurationWrapper" but eventually
    it got reverted in that branch with 13c496b128e5d2bf6686ca1fdf28726009408e55
    "Revert "optimize ConfigurationProperty::get()"" because the crash was
    still being reported.
    In 7.6 branch the revert was also applied in 
05b2bfc289df8712097cc1e640bf7d3bc6b86a84
    "Revert "optimize ConfigurationProperty::get()"" and later reverted with
    3a4a00a51acca8f9b5e775547abff0c4dc9144d7
    "re-apply "optimize ConfigurationProperty::get()""
    However, there have been more than 1200 reports of this crash in
    LibreOffice 7.6.4.1, See
    
https://crashreport.libreoffice.org/stats/signature/void%20rtl::str::release%3C_rtl_uString%3E(_rtl_uString*)#summary
    So revert it in 7.6 branch as well.
    Regarding master and 24.2 branch, let's wait a bit until there
    are some results from 24.2.0
    
    Change-Id: I0a379f51ab5fb5b74c653be46093a71ff4cfc958
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162797
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/comphelper/source/misc/configuration.cxx 
b/comphelper/source/misc/configuration.cxx
index f91e85852831..59631dbccd83 100644
--- a/comphelper/source/misc/configuration.cxx
+++ b/comphelper/source/misc/configuration.cxx
@@ -10,8 +10,11 @@
 #include <sal/config.h>
 
 #include <cassert>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <string_view>
 
-#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>
@@ -21,16 +24,12 @@
 #include <com/sun/star/container/XHierarchicalNameReplace.hpp>
 #include <com/sun/star/container/XNameAccess.hpp>
 #include <com/sun/star/container/XNameContainer.hpp>
-#include <com/sun/star/util/XChangesListener.hpp>
-#include <com/sun/star/util/XChangesNotifier.hpp>
-#include <com/sun/star/lang/DisposedException.hpp>
 #include <com/sun/star/lang/XLocalizable.hpp>
 #include <com/sun/star/uno/Any.hxx>
 #include <com/sun/star/uno/Reference.hxx>
 #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>
@@ -107,67 +106,12 @@ comphelper::detail::ConfigurationWrapper::get()
     return WRAPPER;
 }
 
-class comphelper::detail::ConfigurationChangesListener
-    : public ::cppu::WeakImplHelper<css::util::XChangesListener>
-{
-     comphelper::detail::ConfigurationWrapper& mrConfigurationWrapper;
-public:
-    ConfigurationChangesListener(comphelper::detail::ConfigurationWrapper& 
rWrapper)
-        : mrConfigurationWrapper(rWrapper)
-    {}
-    // util::XChangesListener
-    virtual void SAL_CALL changesOccurred( const css::util::ChangesEvent& ) 
override
-    {
-        std::scoped_lock aGuard(mrConfigurationWrapper.maMutex);
-        mrConfigurationWrapper.maPropertyCache.clear();
-    }
-    virtual void SAL_CALL disposing(const css::lang::EventObject&) override
-    {
-        std::scoped_lock aGuard(mrConfigurationWrapper.maMutex);
-        mrConfigurationWrapper.mbDisposed = true;
-        mrConfigurationWrapper.maPropertyCache.clear();
-        mrConfigurationWrapper.maNotifier.clear();
-        mrConfigurationWrapper.maListener.clear();
-    }
-};
-
 comphelper::detail::ConfigurationWrapper::ConfigurationWrapper():
     context_(comphelper::getProcessComponentContext()),
-    access_(css::configuration::ReadWriteAccess::create(context_, "*")),
-    mbDisposed(false)
-{
-    // 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);
-
-        maNotifier = css::uno::Reference< css::util::XChangesNotifier >(xCfg, 
css::uno::UNO_QUERY);
-        assert(maNotifier.is());
-        maListener = css::uno::Reference< ConfigurationChangesListener >(new 
ConfigurationChangesListener(*this));
-        maNotifier->addChangesListener(maListener);
-    }
-    catch(const css::uno::Exception&)
-    {
-        assert(false);
-    }
-}
+    access_(css::configuration::ReadWriteAccess::create(context_, "*"))
+{}
 
-comphelper::detail::ConfigurationWrapper::~ConfigurationWrapper()
-{
-    maPropertyCache.clear();
-    maNotifier.clear();
-    maListener.clear();
-}
+comphelper::detail::ConfigurationWrapper::~ConfigurationWrapper() {}
 
 bool comphelper::detail::ConfigurationWrapper::isReadOnly(OUString const & 
path)
     const
@@ -178,26 +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(maMutex);
-    if (mbDisposed)
-        throw css::lang::DisposedException();
     // Cache the configuration access, since some of the keys are used in hot 
code.
-    auto it = maPropertyCache.find(path);
-    if( it != maPropertyCache.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);
-    maPropertyCache.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 45228b700944..222b9d5af124 100644
--- a/include/comphelper/configuration.hxx
+++ b/include/comphelper/configuration.hxx
@@ -12,16 +12,15 @@
 
 #include <sal/config.h>
 
+#include <optional>
+#include <string_view>
+
 #include <com/sun/star/uno/Any.hxx>
 #include <com/sun/star/uno/Reference.h>
 #include <comphelper/comphelperdllapi.h>
 #include <comphelper/processfactory.hxx>
 #include <sal/types.h>
 #include <memory>
-#include <mutex>
-#include <optional>
-#include <string_view>
-#include <unordered_map>
 
 namespace com::sun::star {
     namespace configuration { class XReadWriteAccess; }
@@ -32,10 +31,6 @@ namespace com::sun::star {
         class XNameContainer;
     }
     namespace uno { class XComponentContext; }
-    namespace util {
-        class XChangesListener;
-        class XChangesNotifier;
-    }
 }
 
 namespace comphelper {
@@ -85,17 +80,14 @@ private:
 
 namespace detail {
 
-class ConfigurationChangesListener;
-
 /// @internal
 class COMPHELPER_DLLPUBLIC ConfigurationWrapper {
-friend class ConfigurationChangesListener;
 public:
     static ConfigurationWrapper const & get();
 
     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,
@@ -143,12 +135,6 @@ private:
         // css.beans.XHierarchicalPropertySetInfo), but then
         // configmgr::Access::asProperty() would report all properties as
         // READONLY, so isReadOnly() would not work
-
-    mutable std::mutex maMutex;
-    bool mbDisposed;
-    mutable std::unordered_map<OUString, css::uno::Any> maPropertyCache;
-    css::uno::Reference< css::util::XChangesNotifier > maNotifier;
-    css::uno::Reference< css::util::XChangesListener > maListener;
 };
 
 /// @internal

Reply via email to