diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-11-27 17:08:22 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2013-11-27 17:20:31 +0100 |
commit | 6aefcb6a6f90896754f3432e5ae41403998b7ab0 (patch) | |
tree | dd5b8c935cf2c377b307770aa4bc7f1a372d9fca | |
parent | e521a803c914e0d3718ae795976948aabbb9c76c (diff) |
forms: avoid deadlock when setting FontControlModel properties
Deadlock found in forms_unoapi on Windows, with
OGridControlModel::setFastPropertyValue_NoBroadcast() calling event
handler that tries to lock SolarMutex.
FontControlModel::setFastPropertyValue_NoBroadcast() and its callers in
3 other classes must not send events via firePropertyChange()
because they are called by OPropertySetHelper::setFastPropertyValues()
with its Mutex locked.
It is possible (though sadly quite convoluted) to delay the sending of
the events by calling setDependentFastPropertyValue() instead.
Change-Id: I0c767cfec01fe1bcaeb1236287b5faf81a2e7441
-rw-r--r-- | forms/source/component/Grid.cxx | 9 | ||||
-rw-r--r-- | forms/source/component/formcontrolfont.cxx | 118 | ||||
-rw-r--r-- | forms/source/component/navigationbar.cxx | 9 | ||||
-rw-r--r-- | forms/source/inc/formcontrolfont.hxx | 11 | ||||
-rw-r--r-- | forms/source/richtext/richtextmodel.cxx | 9 |
5 files changed, 96 insertions, 60 deletions
diff --git a/forms/source/component/Grid.cxx b/forms/source/component/Grid.cxx index c81675f77084..bb526353e3c9 100644 --- a/forms/source/component/Grid.cxx +++ b/forms/source/component/Grid.cxx @@ -707,12 +707,9 @@ void OGridControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, con default: if ( isFontRelatedProperty( nHandle ) ) { - FontDescriptor aOldFont( getFont() ); - - FontControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); - - if ( isFontAggregateProperty( nHandle ) ) - firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) ); + FontControlModel::setFastPropertyValue_NoBroadcast_impl( + *this, &OGridControlModel::setDependentFastPropertyValue, + nHandle, rValue); } else OControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); diff --git a/forms/source/component/formcontrolfont.cxx b/forms/source/component/formcontrolfont.cxx index 5745802f008f..4b85caebd2f2 100644 --- a/forms/source/component/formcontrolfont.cxx +++ b/forms/source/component/formcontrolfont.cxx @@ -20,6 +20,7 @@ #include "formcontrolfont.hxx" #include "property.hrc" #include "property.hxx" +#include <cppuhelper/propshlp.hxx> #include <comphelper/property.hxx> #include <comphelper/types.hxx> #include <tools/color.hxx> @@ -351,104 +352,139 @@ namespace frm } //------------------------------------------------------------------------------ - void FontControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception ) + static void setFastPropertyValue_NoBroadcast_implimpl( + FontDescriptor & rFont, + sal_Int32 nHandle, const Any& rValue) throw (Exception) { - switch( _nHandle ) + switch (nHandle) { - case PROPERTY_ID_TEXTCOLOR: - m_aTextColor = _rValue; - break; - - case PROPERTY_ID_TEXTLINECOLOR: - m_aTextLineColor = _rValue; - break; - - case PROPERTY_ID_FONTEMPHASISMARK: - _rValue >>= m_nFontEmphasis; - break; - - case PROPERTY_ID_FONTRELIEF: - _rValue >>= m_nFontRelief; - break; - - case PROPERTY_ID_FONT: - _rValue >>= m_aFont; - break; - case PROPERTY_ID_FONT_NAME: - _rValue >>= m_aFont.Name; + rValue >>= rFont.Name; break; case PROPERTY_ID_FONT_STYLENAME: - _rValue >>= m_aFont.StyleName; + rValue >>= rFont.StyleName; break; case PROPERTY_ID_FONT_FAMILY: - _rValue >>= m_aFont.Family; + rValue >>= rFont.Family; break; case PROPERTY_ID_FONT_CHARSET: - _rValue >>= m_aFont.CharSet; + rValue >>= rFont.CharSet; break; case PROPERTY_ID_FONT_CHARWIDTH: - _rValue >>= m_aFont.CharacterWidth; + rValue >>= rFont.CharacterWidth; break; case PROPERTY_ID_FONT_KERNING: - _rValue >>= m_aFont.Kerning; + rValue >>= rFont.Kerning; break; case PROPERTY_ID_FONT_ORIENTATION: - _rValue >>= m_aFont.Orientation; + rValue >>= rFont.Orientation; break; case PROPERTY_ID_FONT_PITCH: - _rValue >>= m_aFont.Pitch; + rValue >>= rFont.Pitch; break; case PROPERTY_ID_FONT_TYPE: - _rValue >>= m_aFont.Type; + rValue >>= rFont.Type; break; case PROPERTY_ID_FONT_WIDTH: - _rValue >>= m_aFont.Width; + rValue >>= rFont.Width; break; case PROPERTY_ID_FONT_HEIGHT: { float nHeight = 0; - _rValue >>= nHeight; - m_aFont.Height = (sal_Int16)nHeight; + rValue >>= nHeight; + rFont.Height = (sal_Int16)nHeight; } break; case PROPERTY_ID_FONT_WEIGHT: - _rValue >>= m_aFont.Weight; + rValue >>= rFont.Weight; break; case PROPERTY_ID_FONT_SLANT: - _rValue >>= m_aFont.Slant; + rValue >>= rFont.Slant; break; case PROPERTY_ID_FONT_UNDERLINE: - _rValue >>= m_aFont.Underline; + rValue >>= rFont.Underline; break; case PROPERTY_ID_FONT_STRIKEOUT: - _rValue >>= m_aFont.Strikeout; + rValue >>= rFont.Strikeout; break; case PROPERTY_ID_FONT_WORDLINEMODE: { sal_Bool bWordLineMode = sal_False; - _rValue >>= bWordLineMode; - m_aFont.WordLineMode = bWordLineMode; + rValue >>= bWordLineMode; + rFont.WordLineMode = bWordLineMode; } break; default: - OSL_FAIL( "FontControlModel::setFastPropertyValue_NoBroadcast: invalid property!" ); + assert(false); // isFontAggregateProperty + } + } + + void FontControlModel::setFastPropertyValue_NoBroadcast_impl( + ::cppu::OPropertySetHelper & rBase, + void (::cppu::OPropertySetHelper::*pSet)(sal_Int32, Any const&), + sal_Int32 nHandle, const Any& rValue) throw (Exception) + { + if (isFontAggregateProperty(nHandle)) + { + // need to fire a event for PROPERTY_ID_FONT too apparently, so: + FontDescriptor font(getFont()); + + // first set new value on backup copy + setFastPropertyValue_NoBroadcast_implimpl(font, nHandle, rValue); + + // then set that as the actual property - will eventually call + // this method recursively again... + (rBase.*pSet)(PROPERTY_ID_FONT, makeAny(font)); +#ifndef NDEBUG + // verify that the nHandle property has the new value + Any tmp; + getFastPropertyValue(tmp, nHandle); + assert(tmp == rValue || PROPERTY_ID_FONT_HEIGHT == nHandle /*rounded*/); +#endif + } + else + { + switch (nHandle) + { + case PROPERTY_ID_TEXTCOLOR: + m_aTextColor = rValue; + break; + + case PROPERTY_ID_TEXTLINECOLOR: + m_aTextLineColor = rValue; + break; + + case PROPERTY_ID_FONTEMPHASISMARK: + rValue >>= m_nFontEmphasis; + break; + + case PROPERTY_ID_FONTRELIEF: + rValue >>= m_nFontRelief; + break; + + case PROPERTY_ID_FONT: + rValue >>= m_aFont; + break; + + default: + SAL_WARN("forms.component", "invalid property: " << nHandle); + } } } diff --git a/forms/source/component/navigationbar.cxx b/forms/source/component/navigationbar.cxx index 9baeea7ff3c8..0aa5311e2dcc 100644 --- a/forms/source/component/navigationbar.cxx +++ b/forms/source/component/navigationbar.cxx @@ -403,12 +403,9 @@ namespace frm } else if ( isFontRelatedProperty( _nHandle ) ) { - FontDescriptor aOldFont( getFont() ); - - FontControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); - - if ( isFontAggregateProperty( _nHandle ) ) - firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) ); + FontControlModel::setFastPropertyValue_NoBroadcast_impl( + *this, &ONavigationBarModel::setDependentFastPropertyValue, + _nHandle, _rValue); } else { diff --git a/forms/source/inc/formcontrolfont.hxx b/forms/source/inc/formcontrolfont.hxx index 4e802baf4f5a..e29d93d177af 100644 --- a/forms/source/inc/formcontrolfont.hxx +++ b/forms/source/inc/formcontrolfont.hxx @@ -25,6 +25,10 @@ #include <com/sun/star/beans/Property.hpp> #include <com/sun/star/lang/IllegalArgumentException.hpp> +namespace cppu { + class OPropertySetHelper; +} + //......................................................................... namespace frm { @@ -74,7 +78,12 @@ namespace frm void getFastPropertyValue ( ::com::sun::star::uno::Any& _rValue, sal_Int32 _nHandle ) const; sal_Bool convertFastPropertyValue ( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw( ::com::sun::star::lang::IllegalArgumentException ); - void setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw ( ::com::sun::star::uno::Exception ); + void setFastPropertyValue_NoBroadcast_impl( + ::cppu::OPropertySetHelper & rBase, + void (::cppu::OPropertySetHelper::*pSet)( + sal_Int32, css::uno::Any const&), + sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) + throw ( ::com::sun::star::uno::Exception ); ::com::sun::star::uno::Any getPropertyDefaultByHandle ( sal_Int32 _nHandle ) const; diff --git a/forms/source/richtext/richtextmodel.cxx b/forms/source/richtext/richtextmodel.cxx index 226baddfb4de..592b0d2656d2 100644 --- a/forms/source/richtext/richtextmodel.cxx +++ b/forms/source/richtext/richtextmodel.cxx @@ -391,12 +391,9 @@ namespace frm } else if ( isFontRelatedProperty( _nHandle ) ) { - FontDescriptor aOldFont( getFont() ); - - FontControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); - - if ( isFontAggregateProperty( _nHandle ) ) - firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) ); + FontControlModel::setFastPropertyValue_NoBroadcast_impl( + *this, &ORichTextModel::setDependentFastPropertyValue, + _nHandle, _rValue); } else { |