comphelper/Library_comphelper.mk                      |    1 
 comphelper/source/property/propshlp.cxx               |  880 ++++++++++++++++++
 include/comphelper/compbase.hxx                       |    6 
 include/comphelper/propshlp.hxx                       |  348 +++++++
 include/comphelper/unoimplbase.hxx                    |   34 
 include/toolkit/controls/unocontrolmodel.hxx          |   37 
 include/toolkit/controls/unocontrols.hxx              |   65 -
 include/toolkit/helper/listenermultiplexer.hxx        |    5 
 toolkit/inc/controls/animatedimages.hxx               |    7 
 toolkit/inc/controls/controlmodelcontainerbase.hxx    |    8 
 toolkit/inc/controls/dialogcontrol.hxx                |   24 
 toolkit/inc/controls/formattedcontrol.hxx             |   14 
 toolkit/inc/controls/roadmapcontrol.hxx               |    2 
 toolkit/inc/controls/tabpagecontainer.hxx             |    2 
 toolkit/inc/controls/tabpagemodel.hxx                 |    2 
 toolkit/inc/controls/tkscrollbar.hxx                  |    2 
 toolkit/inc/controls/unocontrolcontainermodel.hxx     |    2 
 toolkit/source/controls/animatedimages.cxx            |   46 
 toolkit/source/controls/controlmodelcontainerbase.cxx |   18 
 toolkit/source/controls/dialogcontrol.cxx             |   17 
 toolkit/source/controls/formattedcontrol.cxx          |   39 
 toolkit/source/controls/grid/gridcontrol.cxx          |   11 
 toolkit/source/controls/grid/gridcontrol.hxx          |    4 
 toolkit/source/controls/spinningprogress.cxx          |    6 
 toolkit/source/controls/tabpagecontainer.cxx          |    6 
 toolkit/source/controls/tkspinbutton.cxx              |    3 
 toolkit/source/controls/tree/treecontrol.hxx          |    6 
 toolkit/source/controls/unocontrolmodel.cxx           |   96 -
 toolkit/source/controls/unocontrols.cxx               |  148 +--
 29 files changed, 1547 insertions(+), 292 deletions(-)

New commits:
commit 30784e55e484de2790c4b264a50a65acf450c000
Author:     Noel Grandin <[email protected]>
AuthorDate: Wed Mar 8 13:15:39 2023 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Mon Mar 13 06:49:21 2023 +0000

    convert UnoControlModel and friends to use std::mutex
    
    Which means creating a variant of the cppuhelper::OPropertySetHelper
    helper class which uses a std::mutex.
    Since we can do virtual base classes now (which the original could not), 
use that and a new helper
    class comphelper::UnoImplBase to share
        std::mutex m_aMutex;
        bool m_bDisposing;
    fields that the OPropertySetHelper wants to share with the parent class.
    
    Change-Id: I05ad465a3d3653ed4e109137e3e1c58190da8d97
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148474
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index 5238cb65e968..f75dc446cdd2 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -155,6 +155,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
     comphelper/source/property/propertystatecontainer \
     comphelper/source/property/propmultiplex \
     comphelper/source/property/propmultiplex2 \
+    comphelper/source/property/propshlp \
     comphelper/source/property/propstate \
     comphelper/source/streaming/basicio \
     comphelper/source/streaming/memorystream \
diff --git a/comphelper/source/property/propshlp.cxx 
b/comphelper/source/property/propshlp.cxx
new file mode 100644
index 000000000000..3071dfd4a32d
--- /dev/null
+++ b/comphelper/source/property/propshlp.cxx
@@ -0,0 +1,880 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/diagnose.h>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <comphelper/propshlp.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <memory>
+#include <sal/log.hxx>
+
+using namespace osl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace cppu;
+
+namespace comphelper
+{
+extern "C" {
+
+static int compare_OUString_Property_Impl(const void* arg1, const void* arg2) 
SAL_THROW_EXTERN_C()
+{
+    return static_cast<OUString const*>(arg1)->compareTo(static_cast<Property 
const*>(arg2)->Name);
+}
+}
+
+/**
+ * The class which implements the PropertySetInfo interface.
+ */
+
+namespace
+{
+class OPropertySetHelperInfo_Impl : public 
WeakImplHelper<css::beans::XPropertySetInfo>
+{
+    Sequence<Property> aInfos;
+
+public:
+    explicit OPropertySetHelperInfo_Impl(IPropertyArrayHelper& rHelper_);
+
+    // XPropertySetInfo-methods
+    virtual Sequence<Property> SAL_CALL getProperties() override;
+    virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName) 
override;
+    virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName) 
override;
+};
+}
+
+/**
+ * Create an object that implements XPropertySetInfo IPropertyArrayHelper.
+ */
+OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(IPropertyArrayHelper& 
rHelper_)
+    : aInfos(rHelper_.getProperties())
+{
+}
+
+/**
+ * Return the sequence of properties, which are provided through the 
constructor.
+ */
+Sequence<Property> OPropertySetHelperInfo_Impl::getProperties() { return 
aInfos; }
+
+/**
+ * Return the sequence of properties, which are provided through the 
constructor.
+ */
+Property OPropertySetHelperInfo_Impl::getPropertyByName(const OUString& 
PropertyName)
+{
+    Property* pR
+        = static_cast<Property*>(bsearch(&PropertyName, 
aInfos.getConstArray(), aInfos.getLength(),
+                                         sizeof(Property), 
compare_OUString_Property_Impl));
+    if (!pR)
+        throw UnknownPropertyException(PropertyName);
+
+    return *pR;
+}
+
+/**
+ * Return the sequence of properties, which are provided through the 
constructor.
+ */
+sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName(const OUString& 
PropertyName)
+{
+    Property* pR
+        = static_cast<Property*>(bsearch(&PropertyName, 
aInfos.getConstArray(), aInfos.getLength(),
+                                         sizeof(Property), 
compare_OUString_Property_Impl));
+    return pR != nullptr;
+}
+
+OPropertySetHelper::OPropertySetHelper() {}
+
+OPropertySetHelper::OPropertySetHelper(bool 
bIgnoreRuntimeExceptionsWhileFiring)
+    : 
m_bIgnoreRuntimeExceptionsWhileFiring(bIgnoreRuntimeExceptionsWhileFiring)
+{
+}
+
+OPropertySetHelper::OPropertySetHelper(cppu::IEventNotificationHook* 
i_pFireEvents,
+                                       bool 
bIgnoreRuntimeExceptionsWhileFiring)
+    : m_pFireEvents(i_pFireEvents)
+    , 
m_bIgnoreRuntimeExceptionsWhileFiring(bIgnoreRuntimeExceptionsWhileFiring)
+{
+}
+
+/**
+ * You must call disposing before.
+ */
+OPropertySetHelper::~OPropertySetHelper() {}
+
+// XInterface
+Any OPropertySetHelper::queryInterface(const css::uno::Type& rType)
+{
+    return ::cppu::queryInterface(rType, static_cast<XPropertySet*>(this),
+                                  static_cast<XMultiPropertySet*>(this),
+                                  static_cast<XFastPropertySet*>(this));
+}
+
+/**
+ * called from the derivee's XTypeProvider::getTypes implementation
+ */
+css::uno::Sequence<css::uno::Type> OPropertySetHelper::getTypes()
+{
+    return { UnoType<css::beans::XPropertySet>::get(),
+             UnoType<css::beans::XMultiPropertySet>::get(),
+             UnoType<css::beans::XFastPropertySet>::get() };
+}
+
+// ComponentHelper
+void OPropertySetHelper::disposing(std::unique_lock<std::mutex>& rGuard)
+{
+    // Create an event with this as sender
+    Reference<XPropertySet> rSource = this;
+    EventObject aEvt;
+    aEvt.Source = rSource;
+
+    // inform all listeners to release this object
+    // The listener containers are automatically cleared
+    aBoundLC.disposeAndClear(rGuard, aEvt);
+    aVetoableLC.disposeAndClear(rGuard, aEvt);
+}
+
+Reference<XPropertySetInfo>
+OPropertySetHelper::createPropertySetInfo(IPropertyArrayHelper& rProperties)
+{
+    return new OPropertySetHelperInfo_Impl(rProperties);
+}
+
+// XPropertySet
+void OPropertySetHelper::setPropertyValue(const OUString& rPropertyName, const 
Any& rValue)
+{
+    std::unique_lock aGuard(m_aMutex);
+    setPropertyValueImpl(aGuard, rPropertyName, rValue);
+}
+
+void OPropertySetHelper::setPropertyValueImpl(std::unique_lock<std::mutex>& 
rGuard,
+                                              const OUString& rPropertyName, 
const Any& rValue)
+{
+    // get the map table
+    IPropertyArrayHelper& rPH = getInfoHelper();
+    // map the name to the handle
+    sal_Int32 nHandle = rPH.getHandleByName(rPropertyName);
+    // call the method of the XFastPropertySet interface
+    setFastPropertyValueImpl(rGuard, nHandle, rValue);
+}
+
+// XPropertySet
+Any OPropertySetHelper::getPropertyValue(const OUString& rPropertyName)
+{
+    std::unique_lock aGuard(m_aMutex);
+    return getPropertyValueImpl(aGuard, rPropertyName);
+}
+
+Any OPropertySetHelper::getPropertyValueImpl(std::unique_lock<std::mutex>& 
rGuard,
+                                             const OUString& rPropertyName)
+{
+    // get the map table
+    IPropertyArrayHelper& rPH = getInfoHelper();
+    // map the name to the handle
+    sal_Int32 nHandle = rPH.getHandleByName(rPropertyName);
+    // call the method of the XFastPropertySet interface
+    Any aAny;
+    getFastPropertyValue(rGuard, aAny, nHandle);
+    return aAny;
+}
+
+// XPropertySet
+void OPropertySetHelper::addPropertyChangeListener(
+    const OUString& rPropertyName, const Reference<XPropertyChangeListener>& 
rxListener)
+{
+    std::unique_lock aGuard(m_aMutex);
+    OSL_ENSURE(!m_bDisposed, "object is disposed");
+    if (m_bDisposed)
+        return;
+
+    // only add listeners if you are not disposed
+    // a listener with no name means all properties
+    if (!rPropertyName.isEmpty())
+    {
+        // get the map table
+        IPropertyArrayHelper& rPH = getInfoHelper();
+        // map the name to the handle
+        sal_Int32 nHandle = rPH.getHandleByName(rPropertyName);
+        if (nHandle == -1)
+        {
+            // property not known throw exception
+            throw UnknownPropertyException(rPropertyName);
+        }
+
+        sal_Int16 nAttributes;
+        rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle);
+        if (!(nAttributes & css::beans::PropertyAttribute::BOUND))
+        {
+            OSL_FAIL("add listener to an unbound property");
+            // silent ignore this
+            return;
+        }
+        // add the change listener to the helper container
+        aBoundLC.addInterface(aGuard, nHandle, rxListener);
+    }
+    else
+        // add the change listener to the helper container
+        maPropertyChangeListeners.addInterface(aGuard, rxListener);
+}
+
+// XPropertySet
+void OPropertySetHelper::removePropertyChangeListener(
+    const OUString& rPropertyName, const Reference<XPropertyChangeListener>& 
rxListener)
+{
+    std::unique_lock aGuard(m_aMutex);
+    OSL_ENSURE(!m_bDisposed, "object is disposed");
+    // all listeners are automatically released in a dispose call
+    if (m_bDisposed)
+        return;
+
+    if (!rPropertyName.isEmpty())
+    {
+        // get the map table
+        IPropertyArrayHelper& rPH = getInfoHelper();
+        // map the name to the handle
+        sal_Int32 nHandle = rPH.getHandleByName(rPropertyName);
+        if (nHandle == -1)
+            // property not known throw exception
+            throw UnknownPropertyException(rPropertyName);
+        aBoundLC.removeInterface(aGuard, nHandle, rxListener);
+    }
+    else
+    {
+        // remove the change listener to the helper container
+        maPropertyChangeListeners.removeInterface(aGuard, rxListener);
+    }
+}
+
+// XPropertySet
+void OPropertySetHelper::addVetoableChangeListener(
+    const OUString& rPropertyName, const Reference<XVetoableChangeListener>& 
rxListener)
+{
+    std::unique_lock aGuard(m_aMutex);
+    OSL_ENSURE(!m_bDisposed, "object is disposed");
+    if (m_bDisposed)
+        return;
+
+    // only add listeners if you are not disposed
+    // a listener with no name means all properties
+    if (!rPropertyName.isEmpty())
+    {
+        // get the map table
+        IPropertyArrayHelper& rPH = getInfoHelper();
+        // map the name to the handle
+        sal_Int32 nHandle = rPH.getHandleByName(rPropertyName);
+        if (nHandle == -1)
+        {
+            // property not known throw exception
+            throw UnknownPropertyException(rPropertyName);
+        }
+
+        sal_Int16 nAttributes;
+        rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle);
+        if (!(nAttributes & PropertyAttribute::CONSTRAINED))
+        {
+            OSL_FAIL("addVetoableChangeListener, and property is not 
constrained");
+            // silent ignore this
+            return;
+        }
+        // add the vetoable listener to the helper container
+        aVetoableLC.addInterface(aGuard, nHandle, rxListener);
+    }
+    else
+        // add the vetoable listener to the helper container
+        maVetoableChangeListeners.addInterface(aGuard, rxListener);
+}
+
+// XPropertySet
+void OPropertySetHelper::removeVetoableChangeListener(
+    const OUString& rPropertyName, const Reference<XVetoableChangeListener>& 
rxListener)
+{
+    std::unique_lock aGuard(m_aMutex);
+    OSL_ENSURE(!m_bDisposed, "object is disposed");
+    // all listeners are automatically released in a dispose call
+    if (m_bDisposed)
+        return;
+
+    if (!rPropertyName.isEmpty())
+    {
+        // get the map table
+        IPropertyArrayHelper& rPH = getInfoHelper();
+        // map the name to the handle
+        sal_Int32 nHandle = rPH.getHandleByName(rPropertyName);
+        if (nHandle == -1)
+        {
+            // property not known throw exception
+            throw UnknownPropertyException(rPropertyName);
+        }
+        // remove the vetoable listener to the helper container
+        aVetoableLC.removeInterface(aGuard, nHandle, rxListener);
+    }
+    else
+        // add the vetoable listener to the helper container
+        maVetoableChangeListeners.removeInterface(aGuard, rxListener);
+}
+
+void 
OPropertySetHelper::setDependentFastPropertyValue(std::unique_lock<std::mutex>& 
rGuard,
+                                                       sal_Int32 i_handle,
+                                                       const css::uno::Any& 
i_value)
+{
+    sal_Int16 nAttributes(0);
+    IPropertyArrayHelper& rInfo = getInfoHelper();
+    if (!rInfo.fillPropertyMembersByHandle(nullptr, &nAttributes, i_handle))
+        // unknown property
+        throw UnknownPropertyException(OUString::number(i_handle));
+
+    // no need to check for READONLY-ness of the property. The method is 
intended to be called internally, which
+    // implies it might be invoked for properties which are read-only to the 
instance's clients, but well allowed
+    // to change their value.
+
+    Any aConverted, aOld;
+    bool bChanged = convertFastPropertyValue(rGuard, aConverted, aOld, 
i_handle, i_value);
+    if (!bChanged)
+        return;
+
+    // don't fire vetoable events. This method is called with our mutex 
locked, so calling into listeners would not be
+    // a good idea. The caller is responsible for not invoking this for 
constrained properties.
+    OSL_ENSURE((nAttributes & PropertyAttribute::CONSTRAINED) == 0,
+               "OPropertySetHelper::setDependentFastPropertyValue: not to be 
used for constrained "
+               "properties!");
+
+    // actually set the new value
+    try
+    {
+        setFastPropertyValue_NoBroadcast(rGuard, i_handle, aConverted);
+    }
+    catch (const UnknownPropertyException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const PropertyVetoException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const IllegalArgumentException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const WrappedTargetException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const RuntimeException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const Exception&)
+    {
+        // not allowed to leave this method
+        WrappedTargetException aWrapped;
+        aWrapped.TargetException = ::cppu::getCaughtException();
+        aWrapped.Context = static_cast<XPropertySet*>(this);
+        throw aWrapped;
+    }
+
+    // remember the handle/values, for the events to be fired later
+    m_handles.push_back(i_handle);
+    m_newValues.push_back(
+        aConverted); // TODO: setFastPropertyValue notifies the unconverted 
value here ...?
+    m_oldValues.push_back(aOld);
+}
+
+// XFastPropertySet
+void OPropertySetHelper::setFastPropertyValue(sal_Int32 nHandle, const Any& 
rValue)
+{
+    std::unique_lock aGuard(m_aMutex);
+    setFastPropertyValueImpl(aGuard, nHandle, rValue);
+}
+
+void 
OPropertySetHelper::setFastPropertyValueImpl(std::unique_lock<std::mutex>& 
rGuard,
+                                                  sal_Int32 nHandle, const 
Any& rValue)
+{
+    OSL_ENSURE(!m_bDisposed, "object is disposed");
+
+    IPropertyArrayHelper& rInfo = getInfoHelper();
+    sal_Int16 nAttributes;
+    if (!rInfo.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle))
+    {
+        // unknown property
+        throw UnknownPropertyException(OUString::number(nHandle));
+    }
+    if (nAttributes & PropertyAttribute::READONLY)
+        throw PropertyVetoException();
+
+    Any aConvertedVal;
+    Any aOldVal;
+
+    // Will the property change?
+    bool bChanged = convertFastPropertyValue(rGuard, aConvertedVal, aOldVal, 
nHandle, rValue);
+    if (!bChanged)
+        return;
+
+    // Is it a constrained property?
+    if (nAttributes & PropertyAttribute::CONSTRAINED)
+    {
+        // In aValue is the converted rValue
+        // fire a constrained event
+        // second parameter NULL means constrained
+        fire(rGuard, &nHandle, &rValue, &aOldVal, 1, true);
+    }
+
+    try
+    {
+        // set the property to the new value
+        setFastPropertyValue_NoBroadcast(rGuard, nHandle, aConvertedVal);
+    }
+    catch (const css::beans::UnknownPropertyException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const css::beans::PropertyVetoException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const css::lang::IllegalArgumentException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const css::lang::WrappedTargetException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const css::uno::RuntimeException&)
+    {
+        throw; /* allowed to leave */
+    }
+    catch (const css::uno::Exception& e)
+    {
+        // not allowed to leave this method
+        css::lang::WrappedTargetException aWrap;
+        aWrap.Context = static_cast<css::beans::XPropertySet*>(this);
+        aWrap.TargetException <<= e;
+
+        throw aWrap;
+    }
+
+    // file a change event, if the value changed
+    impl_fireAll(rGuard, &nHandle, &rValue, &aOldVal, 1);
+}
+
+// XFastPropertySet
+Any OPropertySetHelper::getFastPropertyValue(sal_Int32 nHandle)
+{
+    IPropertyArrayHelper& rInfo = getInfoHelper();
+    if (!rInfo.fillPropertyMembersByHandle(nullptr, nullptr, nHandle))
+        // unknown property
+        throw UnknownPropertyException(OUString::number(nHandle));
+
+    Any aRet;
+    std::unique_lock aGuard(m_aMutex);
+    getFastPropertyValue(aGuard, aRet, nHandle);
+    return aRet;
+}
+
+void OPropertySetHelper::impl_fireAll(std::unique_lock<std::mutex>& rGuard, 
sal_Int32* i_handles,
+                                      const Any* i_newValues, const Any* 
i_oldValues,
+                                      sal_Int32 i_count)
+{
+    if (m_handles.empty())
+    {
+        fire(rGuard, i_handles, i_newValues, i_oldValues, i_count, false);
+        return;
+    }
+
+    const size_t additionalEvents = m_handles.size();
+    OSL_ENSURE(additionalEvents == m_newValues.size() && additionalEvents == 
m_oldValues.size(),
+               "OPropertySetHelper::impl_fireAll: inconsistency!");
+
+    std::vector<sal_Int32> allHandles(additionalEvents + i_count);
+    std::copy(m_handles.begin(), m_handles.end(), allHandles.begin());
+    std::copy(i_handles, i_handles + i_count, allHandles.begin() + 
additionalEvents);
+
+    std::vector<Any> allNewValues(additionalEvents + i_count);
+    std::copy(m_newValues.begin(), m_newValues.end(), allNewValues.begin());
+    std::copy(i_newValues, i_newValues + i_count, allNewValues.begin() + 
additionalEvents);
+
+    std::vector<Any> allOldValues(additionalEvents + i_count);
+    std::copy(m_oldValues.begin(), m_oldValues.end(), allOldValues.begin());
+    std::copy(i_oldValues, i_oldValues + i_count, allOldValues.begin() + 
additionalEvents);
+
+    m_handles.clear();
+    m_newValues.clear();
+    m_oldValues.clear();
+
+    fire(rGuard, allHandles.data(), allNewValues.data(), allOldValues.data(),
+         additionalEvents + i_count, false);
+}
+
+void OPropertySetHelper::fire(std::unique_lock<std::mutex>& rGuard, sal_Int32* 
pnHandles,
+                              const Any* pNewValues, const Any* pOldValues,
+                              sal_Int32 nHandles, // This is the Count of the 
array
+                              bool bVetoable)
+{
+    if (!m_bFireEvents)
+        return;
+
+    if (m_pFireEvents)
+    {
+        m_pFireEvents->fireEvents(pnHandles, nHandles, bVetoable,
+                                  m_bIgnoreRuntimeExceptionsWhileFiring);
+    }
+
+    // Only fire, if one or more properties changed
+    if (!nHandles)
+        return;
+
+    // create the event sequence of all changed properties
+    Sequence<PropertyChangeEvent> aEvts(nHandles);
+    PropertyChangeEvent* pEvts = aEvts.getArray();
+    Reference<XInterface> xSource(static_cast<XPropertySet*>(this), UNO_QUERY);
+    sal_Int32 i;
+    sal_Int32 nChangesLen = 0;
+    // Loop over all changed properties to fill the event struct
+    for (i = 0; i < nHandles; i++)
+    {
+        // Vetoable fire and constrained attribute set or
+        // Change fire and Changed and bound attribute set
+        IPropertyArrayHelper& rInfo = getInfoHelper();
+        sal_Int16 nAttributes;
+        OUString aPropName;
+        rInfo.fillPropertyMembersByHandle(&aPropName, &nAttributes, 
pnHandles[i]);
+
+        if ((bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED))
+            || (!bVetoable && (nAttributes & PropertyAttribute::BOUND)))
+        {
+            pEvts[nChangesLen].Source = xSource;
+            pEvts[nChangesLen].PropertyName = aPropName;
+            pEvts[nChangesLen].PropertyHandle = pnHandles[i];
+            pEvts[nChangesLen].OldValue = pOldValues[i];
+            pEvts[nChangesLen].NewValue = pNewValues[i];
+            nChangesLen++;
+        }
+    }
+
+    bool bIgnoreRuntimeExceptionsWhileFiring = 
m_bIgnoreRuntimeExceptionsWhileFiring;
+
+    // fire the events for all changed properties
+    for (i = 0; i < nChangesLen; i++)
+    {
+        if (bVetoable) // fire change Events?
+            fireVetoableChangeListeners(
+                rGuard, aVetoableLC.getContainer(rGuard, 
pEvts[i].PropertyHandle), pEvts[i]);
+        else
+            // get the listener container for the property name
+            firePropertyChangeListeners(
+                rGuard, aBoundLC.getContainer(rGuard, 
pEvts[i].PropertyHandle), pEvts[i]);
+
+        // broadcast to all listeners with "" property name
+        if (bVetoable)
+            // fire change Events?
+            fireVetoableChangeListeners(rGuard, &maVetoableChangeListeners, 
pEvts[i]);
+        else
+            firePropertyChangeListeners(rGuard, &maPropertyChangeListeners, 
pEvts[i]);
+    }
+
+    // reduce array to changed properties
+    aEvts.realloc(nChangesLen);
+
+    if (bVetoable)
+        return;
+
+    if (!maPropertiesChangeListeners.getLength(rGuard))
+        return;
+
+    // Here is a Bug, unbound properties are also fired
+    OInterfaceIteratorHelper4 aIt(rGuard, maPropertiesChangeListeners);
+    while (aIt.hasMoreElements())
+    {
+        XPropertiesChangeListener* pL = aIt.next().get();
+        rGuard.unlock();
+        try
+        {
+            try
+            {
+                // fire the whole event sequence to the
+                // XPropertiesChangeListener's
+                pL->propertiesChange(aEvts);
+            }
+            catch (DisposedException& exc)
+            {
+                OSL_ENSURE(exc.Context.is(), "DisposedException without 
Context!");
+                if (exc.Context == pL)
+                {
+                    rGuard.lock();
+                    aIt.remove(rGuard);
+                    rGuard.unlock();
+                }
+                else
+                    throw;
+            }
+        }
+        catch (RuntimeException& exc)
+        {
+            SAL_INFO("cppuhelper", "caught RuntimeException while firing 
listeners: " << exc);
+            if (!bIgnoreRuntimeExceptionsWhileFiring)
+                throw;
+        }
+        rGuard.lock();
+    }
+}
+
+void OPropertySetHelper::fireVetoableChangeListeners(
+    std::unique_lock<std::mutex>& rGuard,
+    
comphelper::OInterfaceContainerHelper4<css::beans::XVetoableChangeListener>* 
pListeners,
+    const css::beans::PropertyChangeEvent& rChangeEvent)
+{
+    if (!pListeners || !pListeners->getLength(rGuard))
+        return;
+    // Iterate over all listeners and send events
+    OInterfaceIteratorHelper4 aIt(rGuard, *pListeners);
+    while (aIt.hasMoreElements())
+    {
+        XVetoableChangeListener* pL = aIt.next().get();
+        rGuard.unlock();
+        try
+        {
+            try
+            {
+                pL->vetoableChange(rChangeEvent);
+            }
+            catch (DisposedException& exc)
+            {
+                OSL_ENSURE(exc.Context.is(), "DisposedException without 
Context!");
+                if (exc.Context == pL)
+                {
+                    rGuard.lock();
+                    aIt.remove(rGuard);
+                    rGuard.unlock();
+                }
+                else
+                    throw;
+            }
+        }
+        catch (RuntimeException& exc)
+        {
+            SAL_INFO("cppuhelper", "caught RuntimeException while firing 
listeners: " << exc);
+            if (!m_bIgnoreRuntimeExceptionsWhileFiring)
+                throw;
+        }
+        rGuard.lock();
+    }
+}
+
+void OPropertySetHelper::firePropertyChangeListeners(
+    std::unique_lock<std::mutex>& rGuard,
+    
comphelper::OInterfaceContainerHelper4<css::beans::XPropertyChangeListener>* 
pListeners,
+    const css::beans::PropertyChangeEvent& rChangeEvent)
+{
+    if (!pListeners || !pListeners->getLength(rGuard))
+        return;
+    // Iterate over all listeners and send events
+    OInterfaceIteratorHelper4 aIt(rGuard, *pListeners);
+    while (aIt.hasMoreElements())
+    {
+        XPropertyChangeListener* pL = aIt.next().get();
+        rGuard.unlock();
+        try
+        {
+            try
+            {
+                pL->propertyChange(rChangeEvent);
+            }
+            catch (DisposedException& exc)
+            {
+                OSL_ENSURE(exc.Context.is(), "DisposedException without 
Context!");
+                if (exc.Context == pL)
+                {
+                    rGuard.lock();
+                    aIt.remove(rGuard);
+                    rGuard.unlock();
+                }
+                else
+                    throw;
+            }
+        }
+        catch (RuntimeException& exc)
+        {
+            SAL_INFO("cppuhelper", "caught RuntimeException while firing 
listeners: " << exc);
+            if (!m_bIgnoreRuntimeExceptionsWhileFiring)
+                throw;
+        }
+        rGuard.lock();
+    }
+}
+
+// OPropertySetHelper
+void OPropertySetHelper::setFastPropertyValues(std::unique_lock<std::mutex>& 
rGuard,
+                                               sal_Int32 nSeqLen, sal_Int32* 
pHandles,
+                                               const Any* pValues, sal_Int32 
nHitCount)
+{
+    OSL_ENSURE(!m_bDisposed, "object is disposed");
+
+    // get the map table
+    IPropertyArrayHelper& rPH = getInfoHelper();
+
+    std::unique_ptr<Any[]> pConvertedValues(new Any[nHitCount]);
+    std::unique_ptr<Any[]> pOldValues(new Any[nHitCount]);
+    sal_Int32 n = 0;
+    sal_Int32 i;
+
+    for (i = 0; i < nSeqLen; i++)
+    {
+        if (pHandles[i] != -1)
+        {
+            sal_Int16 nAttributes;
+            rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, 
pHandles[i]);
+            if (nAttributes & PropertyAttribute::READONLY)
+                throw PropertyVetoException();
+            // Will the property change?
+            if (convertFastPropertyValue(rGuard, pConvertedValues[n], 
pOldValues[n], pHandles[i],
+                                         pValues[i]))
+            {
+                // only increment if the property really change
+                pHandles[n] = pHandles[i];
+                n++;
+            }
+        }
+    }
+
+    // fire vetoable events
+    fire(rGuard, pHandles, pConvertedValues.get(), pOldValues.get(), n, true);
+
+    // Loop over all changed properties
+    for (i = 0; i < n; i++)
+    {
+        // Will the property change?
+        setFastPropertyValue_NoBroadcast(rGuard, pHandles[i], 
pConvertedValues[i]);
+    }
+
+    // fire change events
+    impl_fireAll(rGuard, pHandles, pConvertedValues.get(), pOldValues.get(), 
n);
+}
+
+// XMultiPropertySet
+/**
+ * The sequence may be contain not known properties. The implementation
+ * must ignore these properties.
+ */
+void OPropertySetHelper::setPropertyValues(const Sequence<OUString>& 
rPropertyNames,
+                                           const Sequence<Any>& rValues)
+{
+    sal_Int32 nSeqLen = rPropertyNames.getLength();
+    if (nSeqLen != rValues.getLength())
+        throw IllegalArgumentException("lengths do not match", 
static_cast<XPropertySet*>(this),
+                                       -1);
+    std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nSeqLen]);
+    // get the map table
+    IPropertyArrayHelper& rPH = getInfoHelper();
+    // fill the handle array
+    sal_Int32 nHitCount = rPH.fillHandles(pHandles.get(), rPropertyNames);
+    if (nHitCount == 0)
+        return;
+    std::unique_lock aGuard(m_aMutex);
+    setFastPropertyValues(aGuard, nSeqLen, pHandles.get(), 
rValues.getConstArray(), nHitCount);
+}
+
+// XMultiPropertySet
+Sequence<Any> OPropertySetHelper::getPropertyValues(const Sequence<OUString>& 
rPropertyNames)
+{
+    sal_Int32 nSeqLen = rPropertyNames.getLength();
+    std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nSeqLen]);
+    Sequence<Any> aValues(nSeqLen);
+
+    // get the map table
+    IPropertyArrayHelper& rPH = getInfoHelper();
+    // fill the handle array
+    rPH.fillHandles(pHandles.get(), rPropertyNames);
+
+    Any* pValues = aValues.getArray();
+
+    std::unique_lock aGuard(m_aMutex);
+    // fill the sequence with the values
+    for (sal_Int32 i = 0; i < nSeqLen; i++)
+        getFastPropertyValue(aGuard, pValues[i], pHandles[i]);
+
+    return aValues;
+}
+
+// XMultiPropertySet
+void OPropertySetHelper::addPropertiesChangeListener(
+    const Sequence<OUString>&, const Reference<XPropertiesChangeListener>& 
rListener)
+{
+    std::unique_lock g(m_aMutex);
+    maPropertiesChangeListeners.addInterface(g, rListener);
+}
+
+// XMultiPropertySet
+void OPropertySetHelper::removePropertiesChangeListener(
+    const Reference<XPropertiesChangeListener>& rListener)
+{
+    std::unique_lock g(m_aMutex);
+    maPropertiesChangeListeners.removeInterface(g, rListener);
+}
+
+// XMultiPropertySet
+void OPropertySetHelper::firePropertiesChangeEvent(
+    const Sequence<OUString>& rPropertyNames, const 
Reference<XPropertiesChangeListener>& rListener)
+{
+    sal_Int32 nLen = rPropertyNames.getLength();
+    std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nLen]);
+    IPropertyArrayHelper& rPH = getInfoHelper();
+    rPH.fillHandles(pHandles.get(), rPropertyNames);
+    const OUString* pNames = rPropertyNames.getConstArray();
+
+    // get the count of matching properties
+    sal_Int32 nFireLen = 0;
+    sal_Int32 i;
+    for (i = 0; i < nLen; i++)
+        if (pHandles[i] != -1)
+            nFireLen++;
+
+    Sequence<PropertyChangeEvent> aChanges(nFireLen);
+    PropertyChangeEvent* pChanges = aChanges.getArray();
+
+    {
+        // must lock the mutex outside the loop. So all values are consistent.
+        std::unique_lock aGuard(m_aMutex);
+        Reference<XInterface> xSource(static_cast<XPropertySet*>(this), 
UNO_QUERY);
+        sal_Int32 nFirePos = 0;
+        for (i = 0; i < nLen; i++)
+        {
+            if (pHandles[i] != -1)
+            {
+                pChanges[nFirePos].Source = xSource;
+                pChanges[nFirePos].PropertyName = pNames[i];
+                pChanges[nFirePos].PropertyHandle = pHandles[i];
+                getFastPropertyValue(aGuard, pChanges[nFirePos].OldValue, 
pHandles[i]);
+                pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue;
+                nFirePos++;
+            }
+        }
+        // release guard to fire events
+    }
+    if (nFireLen)
+        rListener->propertiesChange(aChanges);
+}
+
+UnoImplBase::~UnoImplBase() {}
+
+} // end namespace comphelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/compbase.hxx b/include/comphelper/compbase.hxx
index 6cde1fbb5f74..280d3d26b554 100644
--- a/include/comphelper/compbase.hxx
+++ b/include/comphelper/compbase.hxx
@@ -13,6 +13,7 @@
 
 #include <comphelper/comphelperdllapi.h>
 #include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/unoimplbase.hxx>
 #include <cppuhelper/weak.hxx>
 #include <cppuhelper/queryinterface.hxx>
 #include <cppuhelper/implbase.hxx>
@@ -28,7 +29,8 @@ namespace comphelper
     (2) helps to handle the custom where we have conflicting interfaces
         e.g. multiple UNO interfaces that extend css::lang::XComponent
 */
-class COMPHELPER_DLLPUBLIC WeakComponentImplHelperBase : public 
cppu::OWeakObject,
+class COMPHELPER_DLLPUBLIC WeakComponentImplHelperBase : public virtual 
comphelper::UnoImplBase,
+                                                         public 
cppu::OWeakObject,
                                                          public 
css::lang::XComponent
 {
 public:
@@ -56,8 +58,6 @@ protected:
             throw css::lang::DisposedException(OUString(), 
static_cast<cppu::OWeakObject*>(this));
     }
     comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> 
maEventListeners;
-    mutable std::mutex m_aMutex;
-    bool m_bDisposed = false;
 };
 
 template <typename... Ifc>
diff --git a/include/comphelper/propshlp.hxx b/include/comphelper/propshlp.hxx
new file mode 100644
index 000000000000..e982077166cf
--- /dev/null
+++ b/include/comphelper/propshlp.hxx
@@ -0,0 +1,348 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <comphelper/multiinterfacecontainer4.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetOption.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+
+#include <comphelper/comphelperdllapi.h>
+#include <comphelper/unoimplbase.hxx>
+#include <cppuhelper/propshlp.hxx>
+
+namespace comphelper
+{
+/*************************************************************************
+*************************************************************************/
+
+/**
+   This abstract class maps the methods of the interfaces XMultiPropertySet, 
XFastPropertySet
+   and XPropertySet to the methods getInfoHelper, convertFastPropertyValue,
+   setFastPropertyValue_NoBroadcast and getFastPropertyValue. You must derive 
from
+   this class and override the methods.
+   It provides a standard implementation of the XPropertySetInfo.
+
+   This is a modified copy of the cppuhelper::OPropertySetHelper class, except
+   that is uses std::mutex instead of osl::Mutex.
+ */
+class COMPHELPER_DLLPUBLIC OPropertySetHelper : public virtual 
comphelper::UnoImplBase,
+                                                public 
css::beans::XMultiPropertySet,
+                                                public 
css::beans::XFastPropertySet,
+                                                public css::beans::XPropertySet
+{
+public:
+    OPropertySetHelper();
+
+    /** Constructor.
+
+        @param bIgnoreRuntimeExceptionsWhileFiring
+                        indicates whether occurring RuntimeExceptions will be
+                        ignored when firing notifications
+                        (vetoableChange(), propertyChange())
+                        to listeners.
+                        PropertyVetoExceptions may still be thrown.
+                        This flag is useful in an inter-process scenario when
+                        remote bridges may break down
+                        (firing DisposedExceptions).
+    */
+    OPropertySetHelper(bool bIgnoreRuntimeExceptionsWhileFiring);
+
+    /** Constructor.
+
+        @param i_pFireEvents
+                        additional event notifier
+
+        @param bIgnoreRuntimeExceptionsWhileFiring
+                        indicates whether occurring RuntimeExceptions will be
+                        ignored when firing notifications
+                        (vetoableChange(), propertyChange())
+                        to listeners.
+                        PropertyVetoExceptions may still be thrown.
+                        This flag is useful in an inter-process scenario when
+                        remote bridges may break down
+                        (firing DisposedExceptions).
+    */
+    OPropertySetHelper(cppu::IEventNotificationHook* i_pFireEvents,
+                       bool bIgnoreRuntimeExceptionsWhileFiring = false);
+
+    /**
+       Only returns a reference to XMultiPropertySet, XFastPropertySet, 
XPropertySet and
+       XEventListener.
+     */
+    virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& rType) 
override;
+
+    /** eases implementing XTypeProvider::getTypes, returns the types of 
XMultiPropertySet, XFastPropertySet, XPropertySet
+
+        @throws css::uno::RuntimeException
+     */
+    static css::uno::Sequence<css::uno::Type> getTypes();
+
+    /**
+       Send a disposing notification to the listeners
+
+       @see OComponentHelper
+     */
+    void disposing(std::unique_lock<std::mutex>& rGuard);
+
+    /**
+       Throw UnknownPropertyException or PropertyVetoException if the property 
with the name
+       rPropertyName does not exist or is readonly. Otherwise rPropertyName is 
changed to its handle
+       value and setFastPropertyValue is called.
+     */
+    virtual void SAL_CALL setPropertyValue(const ::rtl::OUString& 
rPropertyName,
+                                           const css::uno::Any& aValue) 
override final;
+    /**
+       Throw UnknownPropertyException if the property with the name
+       rPropertyName does not exist.
+     */
+    virtual css::uno::Any SAL_CALL
+    getPropertyValue(const ::rtl::OUString& aPropertyName) override final;
+    /** Ignored if the property is not bound. */
+    virtual void SAL_CALL addPropertyChangeListener(
+        const ::rtl::OUString& aPropertyName,
+        const css::uno::Reference<css::beans::XPropertyChangeListener>& 
aListener) override;
+
+    /** Ignored if the property is not bound. */
+    virtual void SAL_CALL removePropertyChangeListener(
+        const ::rtl::OUString& aPropertyName,
+        const css::uno::Reference<css::beans::XPropertyChangeListener>& 
aListener) override;
+
+    /** Ignored if the property is not constrained. */
+    virtual void SAL_CALL addVetoableChangeListener(
+        const ::rtl::OUString& aPropertyName,
+        const css::uno::Reference<css::beans::XVetoableChangeListener>& 
aListener) override;
+
+    /** Ignored if the property is not constrained. */
+    virtual void SAL_CALL removeVetoableChangeListener(
+        const ::rtl::OUString& aPropertyName,
+        const css::uno::Reference<css::beans::XVetoableChangeListener>& 
aListener) override;
+
+    /**
+       Throw UnknownPropertyException or PropertyVetoException if the property 
with the name
+       rPropertyName does not exist or is readonly. Otherwise the method 
convertFastPropertyValue
+       is called, then the vetoable listeners are notified. After this the 
value of the property
+       is changed with the setFastPropertyValue_NoBroadcast method and the 
bound listeners are
+       notified.
+      */
+    virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle,
+                                               const css::uno::Any& rValue) 
override final;
+
+    /**
+       @exception css::beans::UnknownPropertyException
+         if the property with the handle nHandle does not exist.
+     */
+    virtual css::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) 
override final;
+
+    // XMultiPropertySet
+    virtual void SAL_CALL
+    setPropertyValues(const css::uno::Sequence<::rtl::OUString>& PropertyNames,
+                      const css::uno::Sequence<css::uno::Any>& Values) 
override;
+
+    virtual css::uno::Sequence<css::uno::Any> SAL_CALL
+    getPropertyValues(const css::uno::Sequence<::rtl::OUString>& 
PropertyNames) override;
+
+    virtual void SAL_CALL addPropertiesChangeListener(
+        const css::uno::Sequence<::rtl::OUString>& PropertyNames,
+        const css::uno::Reference<css::beans::XPropertiesChangeListener>& 
Listener) override;
+
+    virtual void SAL_CALL removePropertiesChangeListener(
+        const css::uno::Reference<css::beans::XPropertiesChangeListener>& 
Listener) override;
+
+    virtual void SAL_CALL firePropertiesChangeEvent(
+        const css::uno::Sequence<::rtl::OUString>& PropertyNames,
+        const css::uno::Reference<css::beans::XPropertiesChangeListener>& 
Listener) override;
+
+    /**
+       The property sequence is created in the call. The interface isn't used 
after the call.
+     */
+    static css::uno::Reference<css::beans::XPropertySetInfo>
+    createPropertySetInfo(cppu::IPropertyArrayHelper& rProperties);
+
+protected:
+    /**
+       You must call disposing() before destruction.
+     */
+    ~OPropertySetHelper();
+
+    /** Override this if you need to do something special during 
setPropertyValue */
+    virtual void setPropertyValueImpl(std::unique_lock<std::mutex>& rGuard,
+                                      const ::rtl::OUString& rPropertyName,
+                                      const css::uno::Any& aValue);
+    /** Override this if you need to do something special during 
setFastPropertyValue */
+    virtual void setFastPropertyValueImpl(std::unique_lock<std::mutex>& 
rGuard, sal_Int32 nHandle,
+                                          const css::uno::Any& rValue);
+    /** Override this if you need to do something special during 
getPropertyValue */
+    virtual css::uno::Any getPropertyValueImpl(std::unique_lock<std::mutex>& 
rGuard,
+                                               const ::rtl::OUString& 
aPropertyName);
+
+    /**
+       This method fire events to all registered property listeners.
+       @param pnHandles     the id's of the properties that changed.
+       @param pNewValues    the new values of the properties.
+       @param pOldValues    the old values of the properties.
+       @param nCount        the number of elements in the arrays pnHandles, 
pNewValues and pOldValues.
+       @param bVetoable true means fire to VetoableChangeListener, false means 
fire to
+                  XPropertyChangedListener and XMultiPropertyChangedListener.
+     */
+    void fire(std::unique_lock<std::mutex>& rGuard, sal_Int32* pnHandles,
+              const css::uno::Any* pNewValues, const css::uno::Any* 
pOldValues, sal_Int32 nCount,
+              bool bVetoable);
+
+    /**
+       Set multiple properties with the handles.
+       @param nSeqLen   the length of the arrays pHandles and Values.
+       @param pHandles the handles of the properties. The number of elements
+              in the Values sequence is the length of the handle array. A 
value of -1
+              of a handle means invalid property. These are ignored.
+       @param pValues the values of the properties.
+       @param nHitCount the number of valid entries in the handle array.
+     */
+    void setFastPropertyValues(std::unique_lock<std::mutex>& rGuard, sal_Int32 
nSeqLen,
+                               sal_Int32* pHandles, const css::uno::Any* 
pValues,
+                               sal_Int32 nHitCount);
+
+    /**
+       This abstract method must return the name to index table. This table 
contains all property
+       names and types of this object. The method is not implemented in this 
class.
+     */
+    virtual cppu::IPropertyArrayHelper& getInfoHelper() = 0;
+
+    /**
+       Converted the value rValue and return the result in rConvertedValue and 
the
+       old value in rOldValue. An IllegalArgumentException is thrown.
+       The method is not implemented in this class. After this call the 
vetoable
+       listeners are notified.
+
+       @param rConvertedValue the converted value. Only set if return is true.
+       @param rOldValue the old value. Only set if return is true.
+       @param nHandle the handle of the property.
+       @param rValue the value to be converted
+       @return true if the value converted.
+       @throws css::lang::IllegalArgumentException
+       @throws css::beans::UnknownPropertyException
+       @throws css::uno::RuntimeException
+     */
+    virtual bool convertFastPropertyValue(std::unique_lock<std::mutex>& rGuard,
+                                          css::uno::Any& rConvertedValue, 
css::uno::Any& rOldValue,
+                                          sal_Int32 nHandle, const 
css::uno::Any& rValue)
+        = 0;
+
+    /** The same as setFastPropertyValue; nHandle is always valid.
+        The changes must not be broadcasted in this method.
+        The method is implemented in a derived class.
+
+        @attention
+        Although you are permitted to throw any UNO exception, only the 
following
+        are valid for usage:
+        -- css::beans::UnknownPropertyException
+        -- css::beans::PropertyVetoException
+        -- css::lang::IllegalArgumentException
+        -- css::lang::WrappedTargetException
+        -- css::uno::RuntimeException
+
+        @param nHandle
+               handle
+        @param rValue
+               value
+        @throws css::uno::Exception
+    */
+    virtual void 
setFastPropertyValue_NoBroadcast(std::unique_lock<std::mutex>& rGuard,
+                                                  sal_Int32 nHandle, const 
css::uno::Any& rValue)
+        = 0;
+    /**
+       The same as getFastPropertyValue, but return the value through rValue 
and nHandle
+       is always valid.
+       The method is not implemented in this class.
+     */
+    virtual void getFastPropertyValue(std::unique_lock<std::mutex>& rGuard, 
css::uno::Any& rValue,
+                                      sal_Int32 nHandle) const = 0;
+
+    /** sets an dependent property's value
+
+        <p>Sometimes setting a given property needs to implicitly modify 
another property's value. Calling |setPropertyValue|
+        from within |setFastPropertyValue_NoBroadcast| is not an option here, 
as it would notify the property listeners
+        while our mutex is still locked. Setting the dependent property's 
value directly (e.g. by calling |setFastPropertyValue_NoBroadcast|
+        recursively) is not an option, too, since it would miss firing the 
property change event.</p>
+
+        <p>So, in such cases, you use |setDependentFastPropertyValue| from 
within |setFastPropertyValue_NoBroadcast|.
+        It will convert and actually set the property value (invoking 
|convertFastPropertyValue| and |setFastPropertyValue_NoBroadcast|
+        for the given handle and value), and add the property change event to 
the list of events to be notified
+        when the bottom-most |setFastPropertyValue_NoBroadcast| on the stack 
returns.</p>
+
+        <p><strong>Note</strong>: The method will <em>not</em> invoke veto 
listeners for the property.</p>
+
+        <p><strong>Note</strong>: It's the caller's responsibility to ensure 
that our mutex is locked. This is
+        canonically given when the method is invoked from within 
|setFastPropertyValue_NoBroadcast|, in other
+        contexts, you might need to take own measures.</p>
+    */
+    void setDependentFastPropertyValue(std::unique_lock<std::mutex>& rGuard, 
sal_Int32 i_handle,
+                                       const css::uno::Any& i_value);
+
+private:
+    /**
+       Container for the XPropertyChangedListener. The listeners are inserted 
by handle.
+     */
+    OMultiTypeInterfaceContainerHelperVar4<sal_Int32, 
css::beans::XPropertyChangeListener> aBoundLC;
+    /**
+       Container for the XPropertyVetoableListener. The listeners are inserted 
by handle.
+     */
+    OMultiTypeInterfaceContainerHelperVar4<sal_Int32, 
css::beans::XVetoableChangeListener>
+        aVetoableLC;
+    /**
+       Container for the XPropertyChangedListener where the listeners want to 
listen to all properties.
+     */
+    comphelper::OInterfaceContainerHelper4<css::beans::XPropertyChangeListener>
+        maPropertyChangeListeners;
+    
comphelper::OInterfaceContainerHelper4<css::beans::XPropertiesChangeListener>
+        maPropertiesChangeListeners;
+    /**
+       Container for the XVetoableChangeListener where the listeners want to 
listen to all properties.
+     */
+    comphelper::OInterfaceContainerHelper4<css::beans::XVetoableChangeListener>
+        maVetoableChangeListeners;
+    cppu::IEventNotificationHook* const m_pFireEvents = nullptr;
+    std::vector<sal_Int32> m_handles;
+    std::vector<css::uno::Any> m_newValues;
+    std::vector<css::uno::Any> m_oldValues;
+    bool m_bIgnoreRuntimeExceptionsWhileFiring = false;
+    bool m_bFireEvents = true;
+
+    /** notifies the given changes in property's values, <em>plus</em> all 
property changes collected during recent
+        |setDependentFastPropertyValue| calls.
+    */
+    void impl_fireAll(std::unique_lock<std::mutex>& rGuard, sal_Int32* 
i_handles,
+                      const css::uno::Any* i_newValues, const css::uno::Any* 
i_oldValues,
+                      sal_Int32 i_count);
+
+    void fireVetoableChangeListeners(
+        std::unique_lock<std::mutex>& rGuard,
+        
comphelper::OInterfaceContainerHelper4<css::beans::XVetoableChangeListener>* 
pListeners,
+        const css::beans::PropertyChangeEvent& rChangeEvent);
+    void firePropertyChangeListeners(
+        std::unique_lock<std::mutex>& rGuard,
+        
comphelper::OInterfaceContainerHelper4<css::beans::XPropertyChangeListener>* 
pListeners,
+        const css::beans::PropertyChangeEvent& rChangeEvent);
+};
+
+} // end namespace comphelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/unoimplbase.hxx 
b/include/comphelper/unoimplbase.hxx
new file mode 100644
index 000000000000..a2d6803a09b5
--- /dev/null
+++ b/include/comphelper/unoimplbase.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <comphelper/comphelperdllapi.h>
+#include <mutex>
+
+namespace comphelper
+{
+/**
+This class is meant to be used as a base class for UNO object implementations 
that
+want to use std::mutex for locking.
+It meant to be virtually inherited, so the base class is shared between
+the UNO object and helper classes like comphelper::OPropertySetHelper
+*/
+class COMPHELPER_DLLPUBLIC UnoImplBase
+{
+public:
+    virtual ~UnoImplBase();
+
+protected:
+    mutable std::mutex m_aMutex;
+    bool m_bDisposed = false;
+};
+
+} // namespace comphelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/toolkit/controls/unocontrolmodel.hxx 
b/include/toolkit/controls/unocontrolmodel.hxx
index a3f0516e8157..a33d73b897bc 100644
--- a/include/toolkit/controls/unocontrolmodel.hxx
+++ b/include/toolkit/controls/unocontrolmodel.hxx
@@ -31,7 +31,7 @@
 #include <comphelper/broadcasthelper.hxx>
 #include <toolkit/helper/listenermultiplexer.hxx>
 
-#include <cppuhelper/propshlp.hxx>
+#include <comphelper/propshlp.hxx>
 #include <cppuhelper/implbase6.hxx>
 #include <comphelper/uno3.hxx>
 #include <rtl/ref.hxx>
@@ -43,9 +43,6 @@ namespace com::sun::star::uno { class XComponentContext; }
 
 typedef std::map<sal_uInt16, css::uno::Any> ImplPropertyTable;
 
-
-
-
 typedef ::cppu::WeakAggImplHelper6  <   css::awt::XControlModel
                                     ,   css::beans::XPropertyState
                                     ,   css::io::XPersistObject
@@ -54,9 +51,8 @@ typedef ::cppu::WeakAggImplHelper6  <   
css::awt::XControlModel
                                     ,   css::util::XCloneable
                                     >   UnoControlModel_Base;
 
-class UnoControlModel :public UnoControlModel_Base
-                                        ,public 
comphelper::OMutexAndBroadcastHelper
-                                        ,public ::cppu::OPropertySetHelper
+class UnoControlModel : public UnoControlModel_Base
+                       ,public ::comphelper::OPropertySetHelper
 {
 private:
     ImplPropertyTable                       maData;
@@ -105,7 +101,7 @@ protected:
 #ifdef _MSC_VER
     UnoControlModel() //do not use! needed by MSVC at compile time to satisfy 
WeakAggImplHelper7
         : UnoControlModel_Base()
-        , OPropertySetHelper( m_aBHelper )
+        , OPropertySetHelper()
         , maDisposeListeners( *this )
         , m_xContext( css::uno::Reference< css::uno::XComponentContext >() )
     {
@@ -155,20 +151,25 @@ public:
     css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() 
override;
 
     // ::cppu::OPropertySetHelper
-    ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override = 0;
-    sal_Bool SAL_CALL convertFastPropertyValue( css::uno::Any & 
rConvertedValue, css::uno::Any & rOldValue, sal_Int32 nHandle, const 
css::uno::Any& rValue ) override;
-    void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const 
css::uno::Any& rValue ) override;
-    using cppu::OPropertySetHelper::getFastPropertyValue;
-    void SAL_CALL getFastPropertyValue( css::uno::Any& rValue, sal_Int32 
nHandle ) const override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override = 0;
+    bool convertFastPropertyValue( std::unique_lock<std::mutex>& rGuard, 
css::uno::Any & rConvertedValue, css::uno::Any & rOldValue, sal_Int32 nHandle, 
const css::uno::Any& rValue ) override;
+    void setFastPropertyValue_NoBroadcast(
+                std::unique_lock<std::mutex>& rGuard,
+                sal_Int32 nHandle, const css::uno::Any& rValue ) override;
+    using comphelper::OPropertySetHelper::getFastPropertyValue;
+    void getFastPropertyValue( std::unique_lock<std::mutex>& rGuard, 
css::uno::Any& rValue, sal_Int32 nHandle ) const override;
 
-    // override setValue methods to handle properties of FontDescriptor
-    // css::beans::XPropertySet
-    void SAL_CALL setPropertyValue( const OUString& aPropertyName, const 
css::uno::Any& aValue ) override;
-    // css::beans::XFastPropertySet
-    void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const 
css::uno::Any& aValue ) override;
     // css::beans::XMultiPropertySet
     css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL 
getPropertySetInfo(  ) override;
     void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& 
PropertyNames, const css::uno::Sequence< css::uno::Any >& Values ) override;
+protected:
+    // override setValue methods to handle properties of FontDescriptor
+    // css::beans::XPropertySet
+    virtual void setPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, 
const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+    // css::beans::XFastPropertySet
+    void setFastPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, 
sal_Int32 nHandle, const css::uno::Any& aValue ) override;
+    css::beans::PropertyState getPropertyStateImpl( 
std::unique_lock<std::mutex>& rGuard, const OUString& PropertyName );
+    void setPropertyValuesImpl( std::unique_lock<std::mutex>& rGuard, const 
css::uno::Sequence< OUString >& PropertyNames, const css::uno::Sequence< 
css::uno::Any >& Values );
 };
 
 #endif // INCLUDED_TOOLKIT_CONTROLS_UNOCONTROLMODEL_HXX
diff --git a/include/toolkit/controls/unocontrols.hxx 
b/include/toolkit/controls/unocontrols.hxx
index 121bdec42eb3..1fba20389a8b 100644
--- a/include/toolkit/controls/unocontrols.hxx
+++ b/include/toolkit/controls/unocontrols.hxx
@@ -49,7 +49,7 @@
 #include <cppuhelper/implbase5.hxx>
 #include <cppuhelper/implbase4.hxx>
 #include <cppuhelper/implbase1.hxx>
-#include <comphelper/interfacecontainer3.hxx>
+#include <comphelper/interfacecontainer4.hxx>
 #include <comphelper/uno3.hxx>
 #include <tools/gen.hxx>
 
@@ -79,7 +79,7 @@ public:
 class UnoControlEditModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlEditModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -182,7 +182,7 @@ public:
 class UnoControlFileControlModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlFileControlModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -233,8 +233,8 @@ protected:
     }
     GraphicControlModel( const GraphicControlModel& _rSource ) : 
UnoControlModel( _rSource ), mbAdjustingImagePosition( false ), 
mbAdjustingGraphic( false ) { }
 
-    // ::cppu::OPropertySetHelper
-    void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const 
css::uno::Any& rValue ) override;
+    // ::comphelper::OPropertySetHelper
+    void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& 
rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override;
 
     // UnoControlModel
     css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override;
@@ -248,7 +248,7 @@ private:
 class UnoControlButtonModel final : public GraphicControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlButtonModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -327,7 +327,7 @@ private:
     bool    mbAdjustingImageScaleMode;
 
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                                     UnoControlImageControlModel( const 
css::uno::Reference< css::uno::XComponentContext >& rxContext );
@@ -347,7 +347,7 @@ public:
     css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
 
     // ::cppu::OPropertySetHelper
-    void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const 
css::uno::Any& rValue ) override;
+    void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& 
rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override;
 };
 
 
@@ -386,7 +386,7 @@ public:
 class UnoControlRadioButtonModel final : public GraphicControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlRadioButtonModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -464,7 +464,7 @@ public:
 class UnoControlCheckBoxModel final : public GraphicControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlCheckBoxModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -544,7 +544,7 @@ public:
 class UnoControlFixedHyperlinkModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
     UnoControlFixedHyperlinkModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -615,7 +615,7 @@ public:
 class UnoControlFixedTextModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlFixedTextModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -679,7 +679,7 @@ public:
 class UnoControlGroupBoxModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlGroupBoxModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -777,14 +777,15 @@ public:
     virtual void SAL_CALL removeItemListListener( const css::uno::Reference< 
css::awt::XItemListListener >& Listener ) override;
 
     // OPropertySetHelper
-    void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const 
css::uno::Any& rValue ) override;
+    void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& 
rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override;
 
 protected:
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 private:
-    void    impl_notifyItemListEvent_nolck(
+    void    impl_notifyItemListEvent(
+                std::unique_lock<std::mutex>& rGuard,
                 const sal_Int32 i_nItemPosition,
                 const ::std::optional< OUString >& i_rItemText,
                 const ::std::optional< OUString >& i_rItemImageURL,
@@ -792,30 +793,30 @@ private:
             );
 
     void    impl_handleInsert(
+                std::unique_lock<std::mutex>& rGuard,
                 const sal_Int32 i_nItemPosition,
                 const ::std::optional< OUString >& i_rItemText,
-                const ::std::optional< OUString >& i_rItemImageURL,
-                ::osl::ClearableMutexGuard& i_rClearBeforeNotify
+                const ::std::optional< OUString >& i_rItemImageURL
             );
 
     void    impl_handleRemove(
                 const sal_Int32 i_nItemPosition,
-                ::osl::ClearableMutexGuard& i_rClearBeforeNotify
+                std::unique_lock<std::mutex>& i_rClearBeforeNotify
             );
 
     void    impl_handleModify(
                 const sal_Int32 i_nItemPosition,
                 const ::std::optional< OUString >& i_rItemText,
                 const ::std::optional< OUString >& i_rItemImageURL,
-                ::osl::ClearableMutexGuard& i_rClearBeforeNotify
+                std::unique_lock<std::mutex>& i_rClearBeforeNotify
             );
 
-    void    impl_getStringItemList( ::std::vector< OUString >& o_rStringItems 
) const;
-    void    impl_setStringItemList_nolck( const ::std::vector< OUString >& 
i_rStringItems );
+    void    impl_getStringItemList( std::unique_lock<std::mutex>& rGuard, 
::std::vector< OUString >& o_rStringItems ) const;
+    void    impl_setStringItemList( std::unique_lock<std::mutex>& rGuard, 
const ::std::vector< OUString >& i_rStringItems );
 
 protected:
     std::unique_ptr<UnoControlListBoxModel_Data>  m_xData;
-    ::comphelper::OInterfaceContainerHelper3<css::awt::XItemListListener> 
m_aItemListListeners;
+    ::comphelper::OInterfaceContainerHelper4<css::awt::XItemListListener> 
m_aItemListListeners;
 };
 
 
@@ -901,7 +902,7 @@ private:
 class UnoControlComboBoxModel final : public UnoControlListBoxModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlComboBoxModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -915,7 +916,7 @@ public:
     // css::beans::XMultiPropertySet
     css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL 
getPropertySetInfo(  ) override;
     // OPropertySetHelper
-    void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const 
css::uno::Any& rValue ) override;
+    void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& 
rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override;
 
     // css::lang::XServiceInfo
     OUString SAL_CALL getImplementationName(  ) override;
@@ -1031,7 +1032,7 @@ public:
 class UnoControlDateFieldModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                 UnoControlDateFieldModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -1107,7 +1108,7 @@ public:
 class UnoControlTimeFieldModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlTimeFieldModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -1181,7 +1182,7 @@ public:
 class UnoControlNumericFieldModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                 UnoControlNumericFieldModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -1257,7 +1258,7 @@ public:
 class UnoControlCurrencyFieldModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlCurrencyFieldModel( const 
css::uno::Reference< css::uno::XComponentContext >& rxContext );
@@ -1333,7 +1334,7 @@ public:
 class UnoControlPatternFieldModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlPatternFieldModel( const 
css::uno::Reference< css::uno::XComponentContext >& rxContext );
@@ -1392,7 +1393,7 @@ public:
 class UnoControlProgressBarModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlProgressBarModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
@@ -1448,7 +1449,7 @@ public:
 class UnoControlFixedLineModel final : public UnoControlModel
 {
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 public:
                         UnoControlFixedLineModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
diff --git a/include/toolkit/helper/listenermultiplexer.hxx 
b/include/toolkit/helper/listenermultiplexer.hxx
index f2d9db4e625d..b7113c17ee64 100644
--- a/include/toolkit/helper/listenermultiplexer.hxx
+++ b/include/toolkit/helper/listenermultiplexer.hxx
@@ -100,6 +100,11 @@ public:
         maListeners.disposeAndClear(g, rDisposeEvent);
     }
 
+    void disposeAndClear(std::unique_lock<std::mutex>& rGuard, const 
css::lang::EventObject& rDisposeEvent)
+    {
+        maListeners.disposeAndClear(rGuard, rDisposeEvent);
+    }
+
     sal_Int32 getLength() const
     {
         std::unique_lock g(m_aMutex);
diff --git a/toolkit/inc/controls/animatedimages.hxx 
b/toolkit/inc/controls/animatedimages.hxx
index a341447c5366..fca49bfa39de 100644
--- a/toolkit/inc/controls/animatedimages.hxx
+++ b/toolkit/inc/controls/animatedimages.hxx
@@ -72,10 +72,13 @@ namespace toolkit
                                         virtual ~AnimatedImagesControlModel() 
override;
 
         css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-        ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
-        void SAL_CALL                   setFastPropertyValue_NoBroadcast( 
sal_Int32 nHandle, const css::uno::Any& rValue ) override;
+        ::cppu::IPropertyArrayHelper& getInfoHelper() override;
+        void setFastPropertyValue_NoBroadcast(
+                    std::unique_lock<std::mutex>& rGuard,
+                    sal_Int32 nHandle, const css::uno::Any& rValue ) override;
 
     private:
+        
comphelper::OInterfaceContainerHelper4<css::container::XContainerListener> 
maContainerListeners;
         std::vector< css::uno::Sequence< OUString > >    maImageSets;
     };
 
diff --git a/toolkit/inc/controls/controlmodelcontainerbase.hxx 
b/toolkit/inc/controls/controlmodelcontainerbase.hxx
index 1bbc3f301b16..ae414346c78f 100644
--- a/toolkit/inc/controls/controlmodelcontainerbase.hxx
+++ b/toolkit/inc/controls/controlmodelcontainerbase.hxx
@@ -36,7 +36,7 @@
 #include <cppuhelper/propshlp.hxx>
 #include <com/sun/star/awt/tab/XTabPageModel.hpp>
 #include <com/sun/star/lang/XInitialization.hpp>
-#include <comphelper/interfacecontainer3.hxx>
+#include <comphelper/interfacecontainer4.hxx>
 #include <mutex>
 #include <vector>
 
@@ -78,7 +78,7 @@ public:
 
 protected:
     ContainerListenerMultiplexer        maContainerListeners;
-    ::comphelper::OInterfaceContainerHelper3<css::util::XChangesListener>   
maChangeListeners;
+    ::comphelper::OInterfaceContainerHelper4<css::util::XChangesListener>   
maChangeListeners;
     UnoControlModelHolderVector           maModels;
 
     AllGroups                           maGroups;
@@ -91,7 +91,7 @@ protected:
     void    Clone_Impl(ControlModelContainerBase& _rClone) const;
 protected:
     css::uno::Any          ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&       SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
     UnoControlModelHolderVector::iterator         ImplFindElement( 
std::u16string_view rName );
 
@@ -152,7 +152,7 @@ public:
     virtual void SAL_CALL propertyChange( const 
css::beans::PropertyChangeEvent& evt ) override;
 
     // XEventListener
-    using cppu::OPropertySetHelper::disposing;
+    using comphelper::OPropertySetHelper::disposing;
     virtual void SAL_CALL disposing( const css::lang::EventObject& evt ) 
override;
 
     // XServiceInfo
diff --git a/toolkit/inc/controls/dialogcontrol.hxx 
b/toolkit/inc/controls/dialogcontrol.hxx
index b23c60f445f5..3aaf3e50b135 100644
--- a/toolkit/inc/controls/dialogcontrol.hxx
+++ b/toolkit/inc/controls/dialogcontrol.hxx
@@ -160,13 +160,9 @@ class UnoMultiPageModel final : public 
ControlModelContainerBase
 {
 public:
     UnoMultiPageModel( const css::uno::Reference< css::uno::XComponentContext 
>& rxContext );
+    UnoMultiPageModel(const UnoMultiPageModel& rOther) : 
ControlModelContainerBase(rOther) {}
     virtual ~UnoMultiPageModel() override;
 
-    UnoMultiPageModel(UnoMultiPageModel const &) = default;
-    UnoMultiPageModel(UnoMultiPageModel &&) = default;
-    UnoMultiPageModel & operator =(UnoMultiPageModel const &) = delete; // due 
to ControlModelContainerBase
-    UnoMultiPageModel & operator =(UnoMultiPageModel &&) = delete; // due to 
ControlModelContainerBase
-
     rtl::Reference<UnoControlModel> Clone() const override;
 
     DECLIMPL_SERVICEINFO_DERIVED( UnoMultiPageModel, 
ControlModelContainerBase, "com.sun.star.awt.UnoMultiPageModel" )
@@ -180,7 +176,7 @@ public:
     virtual sal_Bool SAL_CALL getGroupControl(  ) override;
 private:
     virtual css::uno::Any          ImplGetDefaultValue( sal_uInt16 nPropId ) 
const override;
-    ::cppu::IPropertyArrayHelper&       SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 };
 
@@ -239,13 +235,9 @@ class UnoPageModel final : public ControlModelContainerBase
 {
 public:
     UnoPageModel( const css::uno::Reference< css::uno::XComponentContext >& 
rxContext );
+    UnoPageModel(const UnoPageModel& rOther) : 
ControlModelContainerBase(rOther) {}
     virtual ~UnoPageModel() override;
 
-    UnoPageModel(UnoPageModel const &) = default;
-    UnoPageModel(UnoPageModel &&) = default;
-    UnoPageModel & operator =(UnoPageModel const &) = delete; // due to 
ControlModelContainerBase
-    UnoPageModel & operator =(UnoPageModel &&) = delete; // due to 
ControlModelContainerBase
-
     rtl::Reference<UnoControlModel> Clone() const override;
 
     DECLIMPL_SERVICEINFO_DERIVED( UnoPageModel, ControlModelContainerBase, 
"com.sun.star.awt.UnoPageModel" )
@@ -257,7 +249,7 @@ public:
     virtual sal_Bool SAL_CALL getGroupControl(  ) override;
 private:
     virtual css::uno::Any          ImplGetDefaultValue( sal_uInt16 nPropId ) 
const override;
-    ::cppu::IPropertyArrayHelper&       SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
 };
 
@@ -277,13 +269,9 @@ class UnoFrameModel final : public 
ControlModelContainerBase
 {
 public:
     UnoFrameModel( const css::uno::Reference< css::uno::XComponentContext >& 
rxContext );
+    UnoFrameModel(const UnoFrameModel& rOther) : 
ControlModelContainerBase(rOther) {}
     virtual ~UnoFrameModel() override;
 
-    UnoFrameModel(UnoFrameModel const &) = default;
-    UnoFrameModel(UnoFrameModel &&) = default;
-    UnoFrameModel & operator =(UnoFrameModel const &) = delete; // due to 
ControlModelContainerBase
-    UnoFrameModel & operator =(UnoFrameModel &&) = delete; // due to 
ControlModelContainerBase
-
     rtl::Reference<UnoControlModel> Clone() const override;
 
     DECLIMPL_SERVICEINFO_DERIVED( UnoFrameModel, ControlModelContainerBase, 
"com.sun.star.awt.UnoFrameModel" )
@@ -293,7 +281,7 @@ public:
 
 private:
     virtual css::uno::Any          ImplGetDefaultValue( sal_uInt16 nPropId ) 
const override;
-    ::cppu::IPropertyArrayHelper&       SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 };
 
 class UnoFrameControl final : public ControlContainerBase
diff --git a/toolkit/inc/controls/formattedcontrol.hxx 
b/toolkit/inc/controls/formattedcontrol.hxx
index 388d94312aab..c614b42c74d3 100644
--- a/toolkit/inc/controls/formattedcontrol.hxx
+++ b/toolkit/inc/controls/formattedcontrol.hxx
@@ -72,20 +72,22 @@ namespace toolkit
                         css::uno::Any*     _pValues,       /// the values of 
the properties to set
                         sal_Int32*                      _pValidHandles  /// 
pointer to the valid handles, allowed to be adjusted
                     )   const override;
-        void    impl_updateTextFromValue_nothrow();
-        void    impl_updateCachedFormatter_nothrow();
-        void    impl_updateCachedFormatKey_nothrow();
+        void    impl_updateTextFromValue_nothrow(std::unique_lock<std::mutex>& 
rGuard);
+        void    
impl_updateCachedFormatter_nothrow(std::unique_lock<std::mutex>& rGuard);
+        void    
impl_updateCachedFormatKey_nothrow(std::unique_lock<std::mutex>& rGuard);
 
         css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-        ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
-        sal_Bool SAL_CALL convertFastPropertyValue(
+        ::cppu::IPropertyArrayHelper& getInfoHelper() override;
+        bool convertFastPropertyValue(
+                    std::unique_lock<std::mutex>& rGuard,
                     css::uno::Any& rConvertedValue,
                     css::uno::Any& rOldValue,
                     sal_Int32 nPropId,
                     const css::uno::Any& rValue
                 ) override;
 
-        void SAL_CALL setFastPropertyValue_NoBroadcast(
+        void setFastPropertyValue_NoBroadcast(
+                    std::unique_lock<std::mutex>& rGuard,
                     sal_Int32 nHandle,
                     const css::uno::Any& rValue
                 ) override;
diff --git a/toolkit/inc/controls/roadmapcontrol.hxx 
b/toolkit/inc/controls/roadmapcontrol.hxx
index cfc7fbdb9c74..cb6e2cec4533 100644
--- a/toolkit/inc/controls/roadmapcontrol.hxx
+++ b/toolkit/inc/controls/roadmapcontrol.hxx
@@ -83,7 +83,7 @@ namespace toolkit
         sal_Int32                           GetUniqueID();
 
         css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-        ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
+        ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
     public:
         UnoControlRoadmapModel( const css::uno::Reference< 
css::uno::XComponentContext >& i_factory );
diff --git a/toolkit/inc/controls/tabpagecontainer.hxx 
b/toolkit/inc/controls/tabpagecontainer.hxx
index d8cc32664406..f9fe2df02d50 100644
--- a/toolkit/inc/controls/tabpagecontainer.hxx
+++ b/toolkit/inc/controls/tabpagecontainer.hxx
@@ -43,7 +43,7 @@ private:
     ContainerListenerMultiplexer        maContainerListeners;
 
     css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
     // css::beans::XMultiPropertySet
     css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL 
getPropertySetInfo(  ) override;
 
diff --git a/toolkit/inc/controls/tabpagemodel.hxx 
b/toolkit/inc/controls/tabpagemodel.hxx
index 6c12981b28e9..48a84fe5a602 100644
--- a/toolkit/inc/controls/tabpagemodel.hxx
+++ b/toolkit/inc/controls/tabpagemodel.hxx
@@ -26,7 +26,7 @@
 class UnoControlTabPageModel final : public ControlModelContainerBase
 {
     css::uno::Any          ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&       SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 public:
     UnoControlTabPageModel( css::uno::Reference< css::uno::XComponentContext > 
const & i_factory);
 
diff --git a/toolkit/inc/controls/tkscrollbar.hxx 
b/toolkit/inc/controls/tkscrollbar.hxx
index ec774fa9dfb3..c7948de072e5 100644
--- a/toolkit/inc/controls/tkscrollbar.hxx
+++ b/toolkit/inc/controls/tkscrollbar.hxx
@@ -33,7 +33,7 @@ namespace toolkit
     class UnoControlScrollBarModel final : public UnoControlModel
     {
         css::uno::Any      ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-        ::cppu::IPropertyArrayHelper&   SAL_CALL getInfoHelper() override;
+        ::cppu::IPropertyArrayHelper& getInfoHelper() override;
 
     public:
                             UnoControlScrollBarModel( const 
css::uno::Reference< css::uno::XComponentContext >& i_factory );
diff --git a/toolkit/inc/controls/unocontrolcontainermodel.hxx 
b/toolkit/inc/controls/unocontrolcontainermodel.hxx
index 4fe48cdcab6f..83db8af31b7c 100644
--- a/toolkit/inc/controls/unocontrolcontainermodel.hxx
+++ b/toolkit/inc/controls/unocontrolcontainermodel.hxx
@@ -27,7 +27,7 @@
 class UnoControlContainerModel final : public UnoControlModel
 {
     css::uno::Any                                                      
ImplGetDefaultValue( sal_uInt16 nPropId ) const override;
-    ::cppu::IPropertyArrayHelper&                                              
     SAL_CALL getInfoHelper() override;
+    ::cppu::IPropertyArrayHelper&                                      
getInfoHelper() override;
 
 public:
                         UnoControlContainerModel( const css::uno::Reference< 
css::uno::XComponentContext >& i_factory );
diff --git a/toolkit/source/controls/animatedimages.cxx 
b/toolkit/source/controls/animatedimages.cxx
index d188ab20960b..5d8267998496 100644
--- a/toolkit/source/controls/animatedimages.cxx
+++ b/toolkit/source/controls/animatedimages.cxx
@@ -211,12 +211,11 @@ namespace toolkit {
                 throw IndexOutOfBoundsException( OUString(), i_context );
         }
 
-        void lcl_notify( ::osl::ClearableMutexGuard& i_guard, 
::cppu::OBroadcastHelper const & i_broadcaseHelper,
+        void lcl_notify( std::unique_lock<std::mutex>& i_guard, 
comphelper::OInterfaceContainerHelper4<XContainerListener>& rContainer,
             void ( SAL_CALL XContainerListener::*i_notificationMethod )( const 
ContainerEvent& ),
             const sal_Int32 i_accessor, const Sequence< OUString >& 
i_imageURLs, const Reference< XInterface >& i_context )
         {
-            ::cppu::OInterfaceContainerHelper* pContainerListeners = 
i_broadcaseHelper.getContainer( cppu::UnoType<XContainerListener>::get() );
-            if ( pContainerListeners == nullptr )
+            if ( !rContainer.getLength(i_guard) )
                 return;
 
             ContainerEvent aEvent;
@@ -224,8 +223,7 @@ namespace toolkit {
             aEvent.Accessor <<= i_accessor;
             aEvent.Element <<= i_imageURLs;
 
-            i_guard.clear();
-            pContainerListeners->notifyEach( i_notificationMethod, aEvent );
+            rContainer.notifyEach( i_guard, i_notificationMethod, aEvent );
         }
     }
 
@@ -289,7 +287,7 @@ namespace toolkit {
     }
 
 
-    void SAL_CALL 
AnimatedImagesControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 
i_handle, const Any& i_value )
+    void AnimatedImagesControlModel::setFastPropertyValue_NoBroadcast( 
std::unique_lock<std::mutex>& rGuard, sal_Int32 i_handle, const Any& i_value )
     {
         switch ( i_handle )
         {
@@ -306,7 +304,7 @@ namespace toolkit {
         break;
         }
 
-        AnimatedImagesControlModel_Base::setFastPropertyValue_NoBroadcast( 
i_handle, i_value );
+        AnimatedImagesControlModel_Base::setFastPropertyValue_NoBroadcast( 
rGuard, i_handle, i_value );
     }
 
 
@@ -335,7 +333,7 @@ namespace toolkit {
     }
 
 
-    ::cppu::IPropertyArrayHelper& SAL_CALL 
AnimatedImagesControlModel::getInfoHelper()
+    ::cppu::IPropertyArrayHelper& AnimatedImagesControlModel::getInfoHelper()
     {
         static UnoPropertyArrayHelper aHelper( ImplGetPropertyIds() );
         return aHelper;
@@ -386,8 +384,8 @@ namespace toolkit {
 
     ::sal_Int32 SAL_CALL AnimatedImagesControlModel::getImageSetCount(  )
     {
-        ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
-        if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose 
)
+        std::unique_lock aGuard( m_aMutex );
+        if ( m_bDisposed )
             throw DisposedException();
 
         return maImageSets.size();
@@ -396,8 +394,8 @@ namespace toolkit {
 
     Sequence< OUString > SAL_CALL AnimatedImagesControlModel::getImageSet( 
::sal_Int32 i_index )
     {
-        ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
-        if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose 
)
+        std::unique_lock aGuard( m_aMutex );
+        if ( m_bDisposed )
             throw DisposedException();
 
         lcl_checkIndex( maImageSets, i_index, *this );
@@ -408,9 +406,9 @@ namespace toolkit {
 
     void SAL_CALL AnimatedImagesControlModel::insertImageSet( ::sal_Int32 
i_index, const Sequence< OUString >& i_imageURLs )
     {
-        ::osl::ClearableMutexGuard aGuard( GetMutex() );
+        std::unique_lock aGuard( m_aMutex );
         // sanity checks
-        if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose 
)
+        if ( m_bDisposed )
             throw DisposedException();
 
         lcl_checkIndex( maImageSets, i_index, *this, true );
@@ -419,15 +417,15 @@ namespace toolkit {
         maImageSets.insert( maImageSets.begin() + i_index, i_imageURLs );
 
         // listener notification
-        lcl_notify( aGuard, m_aBHelper, &XContainerListener::elementInserted, 
i_index, i_imageURLs, *this );
+        lcl_notify( aGuard, maContainerListeners, 
&XContainerListener::elementInserted, i_index, i_imageURLs, *this );
     }
 
 
     void SAL_CALL AnimatedImagesControlModel::replaceImageSet( ::sal_Int32 
i_index, const Sequence< OUString >& i_imageURLs )
     {
-        ::osl::ClearableMutexGuard aGuard( GetMutex() );
+        std::unique_lock aGuard( m_aMutex );
         // sanity checks
-        if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose 
)
+        if ( m_bDisposed )
             throw DisposedException();
 
         lcl_checkIndex( maImageSets, i_index, *this );
@@ -436,15 +434,15 @@ namespace toolkit {
         maImageSets[ i_index ] = i_imageURLs;
 
         // listener notification
-        lcl_notify( aGuard, m_aBHelper, &XContainerListener::elementReplaced, 
i_index, i_imageURLs, *this );
+        lcl_notify( aGuard, maContainerListeners, 
&XContainerListener::elementReplaced, i_index, i_imageURLs, *this );
     }
 
 
     void SAL_CALL AnimatedImagesControlModel::removeImageSet( ::sal_Int32 
i_index )
     {
-        ::osl::ClearableMutexGuard aGuard( GetMutex() );
+        std::unique_lock aGuard( m_aMutex );
         // sanity checks
-        if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose 
)
+        if ( m_bDisposed )
             throw DisposedException();
 
         lcl_checkIndex( maImageSets, i_index, *this );
@@ -455,19 +453,21 @@ namespace toolkit {
         maImageSets.erase( removalPos );
 
         // listener notification
-        lcl_notify( aGuard, m_aBHelper, &XContainerListener::elementRemoved, 
i_index, aRemovedElement, *this );
+        lcl_notify( aGuard, maContainerListeners, 
&XContainerListener::elementRemoved, i_index, aRemovedElement, *this );
     }
 
 
     void SAL_CALL AnimatedImagesControlModel::addContainerListener( const 
Reference< XContainerListener >& i_listener )
     {
-        m_aBHelper.addListener( cppu::UnoType<XContainerListener>::get(), 
i_listener );
+        std::unique_lock aGuard( m_aMutex );
+        maContainerListeners.addInterface( aGuard, i_listener );
     }
 
 
     void SAL_CALL AnimatedImagesControlModel::removeContainerListener( const 
Reference< XContainerListener >& i_listener )
     {
-        m_aBHelper.removeListener( cppu::UnoType<XContainerListener>::get(), 
i_listener );
+        std::unique_lock aGuard( m_aMutex );
+        maContainerListeners.removeInterface( aGuard, i_listener );
     }
 
 }
diff --git a/toolkit/source/controls/controlmodelcontainerbase.cxx 
b/toolkit/source/controls/controlmodelcontainerbase.cxx
index b0b37df4cbf7..bec15994a034 100644
--- a/toolkit/source/controls/controlmodelcontainerbase.cxx
+++ b/toolkit/source/controls/controlmodelcontainerbase.cxx
@@ -168,7 +168,6 @@ static OUString getStepPropertyName( )
 ControlModelContainerBase::ControlModelContainerBase( const Reference< 
XComponentContext >& rxContext )
     :ControlModelContainer_IBase( rxContext )
     ,maContainerListeners( *this )
-    ,maChangeListeners ( GetMutex() )
     ,mbGroupsUpToDate( false )
     ,m_nTabPageId(0)
 {
@@ -178,7 +177,6 @@ ControlModelContainerBase::ControlModelContainerBase( const 
Reference< XComponen
 ControlModelContainerBase::ControlModelContainerBase( const 
ControlModelContainerBase& rModel )
     : ControlModelContainer_IBase( rModel )
     , maContainerListeners( *this )
-    , maChangeListeners ( GetMutex() )
     , mbGroupsUpToDate( false )
     , m_nTabPageId( rModel.m_nTabPageId )
 {
@@ -217,13 +215,13 @@ void SAL_CALL ControlModelContainerBase::dispose(  )
 
     // tell our listeners
     {
-        ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
+        std::unique_lock aGuard( m_aMutex );
 
         EventObject aDisposeEvent;
         aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< 
::cppu::OWeakAggObject* >( this ) );
 
-        maContainerListeners.disposeAndClear( aDisposeEvent );
-        maChangeListeners.disposeAndClear( aDisposeEvent );
+        maContainerListeners.disposeAndClear( aGuard, aDisposeEvent );
+        maChangeListeners.disposeAndClear( aGuard, aDisposeEvent );
     }
 
 
@@ -848,13 +846,15 @@ void SAL_CALL ControlModelContainerBase::getGroupByName( 
const OUString& _rName,
 
 void SAL_CALL ControlModelContainerBase::addChangesListener( const Reference< 
XChangesListener >& _rxListener )
 {
-    maChangeListeners.addInterface( _rxListener );
+    std::unique_lock g(m_aMutex);
+    maChangeListeners.addInterface( g, _rxListener );
 }
 
 
 void SAL_CALL ControlModelContainerBase::removeChangesListener( const 
Reference< XChangesListener >& _rxListener )
 {
-    maChangeListeners.removeInterface( _rxListener );
+    std::unique_lock g(m_aMutex);
+    maChangeListeners.removeInterface( g, _rxListener );
 }
 
 
@@ -869,7 +869,9 @@ void ControlModelContainerBase::implNotifyTabModelChange( 
const OUString& _rAcce
     aEvent.Changes.getArray()[ 0 ].Accessor <<= _rAccessor;
 
 
-    std::vector< Reference< css::util::XChangesListener > > aChangeListeners( 
maChangeListeners.getElements() );
+    std::unique_lock g(m_aMutex);
+    std::vector< Reference< css::util::XChangesListener > > aChangeListeners( 
maChangeListeners.getElements(g) );
+    g.unlock();
     for ( const auto& rListener : aChangeListeners )
         rListener->changesOccurred( aEvent );
 }
diff --git a/toolkit/source/controls/dialogcontrol.cxx 
b/toolkit/source/controls/dialogcontrol.cxx
index 67ee3bcc6719..b9027cbf17d7 100644
--- a/toolkit/source/controls/dialogcontrol.cxx
+++ b/toolkit/source/controls/dialogcontrol.cxx
@@ -137,9 +137,9 @@ class UnoControlDialogModel :   public 
ControlModelContainerBase
 protected:
     css::uno::Reference< css::graphic::XGraphicObject > mxGrfObj;
     css::uno::Any          ImplGetDefaultValue( sal_uInt16 nPropId ) const 
override;
-    ::cppu::IPropertyArrayHelper&       SAL_CALL getInfoHelper() override;
-    // ::cppu::OPropertySetHelper
-    void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const 
css::uno::Any& rValue ) override;
+    ::cppu::IPropertyArrayHelper& getInfoHelper() override;
+    // ::comphelper::OPropertySetHelper
+    void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& 
rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override;
 public:
     explicit UnoControlDialogModel( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext );
     UnoControlDialogModel( const UnoControlDialogModel& rModel );
@@ -213,7 +213,8 @@ UnoControlDialogModel::UnoControlDialogModel( const 
UnoControlDialogModel& rMode
         if ( xSrcNameCont->hasByName( name ) )
             xNameCont->insertByName( name, xSrcNameCont->getByName( name ) );
     }
-    setFastPropertyValue_NoBroadcast( BASEPROPERTY_USERFORMCONTAINEES, Any( 
xNameCont ) );
+    std::unique_lock aGuard(m_aMutex);
+    setFastPropertyValue_NoBroadcast( aGuard, BASEPROPERTY_USERFORMCONTAINEES, 
Any( xNameCont ) );
 }
 
 rtl::Reference<UnoControlModel> UnoControlDialogModel::Clone() const
@@ -267,9 +268,9 @@ Reference< XPropertySetInfo > 
UnoControlDialogModel::getPropertySetInfo(  )
     return xInfo;
 }
 
-void SAL_CALL UnoControlDialogModel::setFastPropertyValue_NoBroadcast( 
sal_Int32 nHandle, const css::uno::Any& rValue )
+void UnoControlDialogModel::setFastPropertyValue_NoBroadcast( 
std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& 
rValue )
 {
-    ControlModelContainerBase::setFastPropertyValue_NoBroadcast( nHandle, 
rValue );
+    ControlModelContainerBase::setFastPropertyValue_NoBroadcast( rGuard, 
nHandle, rValue );
     try
     {
         if ( nHandle == BASEPROPERTY_IMAGEURL && ImplHasProperty( 
BASEPROPERTY_GRAPHIC ) )
@@ -278,14 +279,14 @@ void SAL_CALL 
UnoControlDialogModel::setFastPropertyValue_NoBroadcast( sal_Int32
             uno::Reference<graphic::XGraphic> xGraphic;
             if (rValue >>= sImageURL)
             {
-                setPropertyValue(
+                setPropertyValueImpl(rGuard,
                     GetPropertyName(BASEPROPERTY_GRAPHIC),
                     
uno::Any(ImageHelper::getGraphicAndGraphicObjectFromURL_nothrow(
                         mxGrfObj, sImageURL)));
             }
             else if (rValue >>= xGraphic)
             {
-                setPropertyValue("Graphic", uno::Any(xGraphic));
+                setPropertyValueImpl(rGuard, "Graphic", uno::Any(xGraphic));
             }
         }
     }
diff --git a/toolkit/source/controls/formattedcontrol.cxx 
b/toolkit/source/controls/formattedcontrol.cxx
index e96a6986a7d0..ff34f4cbdda7 100644
--- a/toolkit/source/controls/formattedcontrol.cxx
+++ b/toolkit/source/controls/formattedcontrol.cxx
@@ -154,39 +154,39 @@ namespace toolkit
     }
 
 
-    void SAL_CALL 
UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 
nHandle, const Any& rValue )
+    void UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( 
std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const Any& rValue )
     {
-        UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+        UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard, nHandle, 
rValue );
 
         switch ( nHandle )
         {
         case BASEPROPERTY_EFFECTIVE_VALUE:
             if ( !m_bSettingValueAndText )
-                impl_updateTextFromValue_nothrow();
+                impl_updateTextFromValue_nothrow(rGuard);
             break;
         case BASEPROPERTY_FORMATSSUPPLIER:
-            impl_updateCachedFormatter_nothrow();
-            impl_updateTextFromValue_nothrow();
+            impl_updateCachedFormatter_nothrow(rGuard);
+            impl_updateTextFromValue_nothrow(rGuard);
             break;
         case BASEPROPERTY_FORMATKEY:
-            impl_updateCachedFormatKey_nothrow();
-            impl_updateTextFromValue_nothrow();
+            impl_updateCachedFormatKey_nothrow(rGuard);
+            impl_updateTextFromValue_nothrow(rGuard);
             break;
         }
     }
 
 
-    void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow()
+    void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow( 
std::unique_lock<std::mutex>& rGuard)
     {
         if ( !m_xCachedFormatter.is() )
-            impl_updateCachedFormatter_nothrow();
+            impl_updateCachedFormatter_nothrow(rGuard);
         if ( !m_xCachedFormatter.is() )
             return;
 
         try
         {
             Any aEffectiveValue;
-            getFastPropertyValue( aEffectiveValue, 
BASEPROPERTY_EFFECTIVE_VALUE );
+            getFastPropertyValue( rGuard, aEffectiveValue, 
BASEPROPERTY_EFFECTIVE_VALUE );
 
             OUString sStringValue;
             if ( !( aEffectiveValue >>= sStringValue ) )
@@ -201,7 +201,7 @@ namespace toolkit
                 }
             }
 
-            setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), Any( 
sStringValue ) );
+            setPropertyValueImpl( rGuard, GetPropertyName( BASEPROPERTY_TEXT 
), Any( sStringValue ) );
         }
         catch( const Exception& )
         {
@@ -210,10 +210,10 @@ namespace toolkit
     }
 
 
-    void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow()
+    void 
UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow(std::unique_lock<std::mutex>&
 rGuard)
     {
         Any aFormatsSupplier;
-        getFastPropertyValue( aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER );
+        getFastPropertyValue( rGuard, aFormatsSupplier, 
BASEPROPERTY_FORMATSSUPPLIER );
         try
         {
             Reference< XNumberFormatsSupplier > xSupplier( aFormatsSupplier, 
UNO_QUERY );
@@ -236,10 +236,10 @@ namespace toolkit
     }
 
 
-    void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow()
+    void 
UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow(std::unique_lock<std::mutex>&
 rGuard)
     {
         Any aFormatKey;
-        getFastPropertyValue( aFormatKey, BASEPROPERTY_FORMATKEY );
+        getFastPropertyValue( rGuard, aFormatKey, BASEPROPERTY_FORMATKEY );
         m_aCachedFormat = aFormatKey;
     }
 
@@ -248,7 +248,7 @@ namespace toolkit
     {
         UnoControlModel::dispose();
 
-        ::osl::MutexGuard aGuard( GetMutex() );
+        std::unique_lock aGuard( m_aMutex );
         if ( !m_bRevokedAsClient )
         {
             lcl_revokeDefaultFormatsClient();
@@ -305,7 +305,8 @@ namespace toolkit
     }
 
 
-    sal_Bool UnoControlFormattedFieldModel::convertFastPropertyValue(
+    bool UnoControlFormattedFieldModel::convertFastPropertyValue(
+                std::unique_lock<std::mutex>& rGuard,
                 Any& rConvertedValue, Any& rOldValue, sal_Int32 nPropId,
                 const Any& rValue )
     {
@@ -338,7 +339,7 @@ namespace toolkit
 
             if ( bStreamed )
             {
-                getFastPropertyValue( rOldValue, nPropId );
+                getFastPropertyValue( rGuard, rOldValue, nPropId );
                 return !CompareProperties( rConvertedValue, rOldValue );
             }
 
@@ -350,7 +351,7 @@ namespace toolkit
                 1);
         }
 
-        return UnoControlModel::convertFastPropertyValue( rConvertedValue, 
rOldValue, nPropId, rValue );
+        return UnoControlModel::convertFastPropertyValue( rGuard, 
rConvertedValue, rOldValue, nPropId, rValue );
     }
 
 
diff --git a/toolkit/source/controls/grid/gridcontrol.cxx 
b/toolkit/source/controls/grid/gridcontrol.cxx
index 106e704067aa..d6071046afc8 100644
--- a/toolkit/source/controls/grid/gridcontrol.cxx
+++ b/toolkit/source/controls/grid/gridcontrol.cxx
@@ -130,7 +130,8 @@ UnoGridModel::UnoGridModel( const UnoGridModel& rModel )
         }
         if ( !xDataModel.is() )

... etc. - the rest is truncated

Reply via email to