summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsb <sb@openoffice.org>2010-04-20 10:44:53 +0200
committersb <sb@openoffice.org>2010-04-20 10:44:53 +0200
commita19cd21e3c03559877428315bebc0ceaf367a461 (patch)
treeceb4514bdf1b9442d600a0a88f4671e6b82a8d2b
parent9d177d6fd3a8fa55fda4eac2b412cd183fa853f0 (diff)
sb120: #i109916# prevent frm::OInterfaceContainer::fakeVbaEventsHack deadlock (patch by fs)
-rw-r--r--forms/source/inc/InterfaceContainer.hxx2
-rw-r--r--forms/source/misc/InterfaceContainer.cxx117
2 files changed, 62 insertions, 57 deletions
diff --git a/forms/source/inc/InterfaceContainer.hxx b/forms/source/inc/InterfaceContainer.hxx
index 427d0c6ed190..90e508f43ca8 100644
--- a/forms/source/inc/InterfaceContainer.hxx
+++ b/forms/source/inc/InterfaceContainer.hxx
@@ -273,7 +273,7 @@ protected:
private:
// hack for Vba Events
- void fakeVbaEventsHack( sal_Int32 _nIndex );
+ void impl_addVbEvents_nolck_nothrow( const sal_Int32 i_nIndex );
// the runtime event format has changed from version SO5.2 to OOo
enum EventFormat
diff --git a/forms/source/misc/InterfaceContainer.cxx b/forms/source/misc/InterfaceContainer.cxx
index b594df158d17..e494406f87ef 100644
--- a/forms/source/misc/InterfaceContainer.cxx
+++ b/forms/source/misc/InterfaceContainer.cxx
@@ -31,6 +31,7 @@
#include "frm_resource.hrc"
#include "frm_resource.hxx"
#include "InterfaceContainer.hxx"
+#include "componenttools.hxx"
#include "property.hrc"
#include "services.hxx"
@@ -40,6 +41,7 @@
#include <com/sun/star/io/XMarkableStream.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/form/XForm.hpp>
#include <comphelper/container.hxx>
#include <comphelper/enumhelper.hxx>
@@ -119,54 +121,52 @@ lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
return sStripped;
}
-void
-OInterfaceContainer::fakeVbaEventsHack( sal_Int32 _nIndex )
+void OInterfaceContainer::impl_addVbEvents_nolck_nothrow( const sal_Int32 i_nIndex )
{
// we are dealing with form controls
try
{
- Reference< XFormComponent > xForm( static_cast< XContainer* >(this), UNO_QUERY_THROW );
- // grand-parent should be the model, no parent ? if not
- // we'll ignore, we'll get called back here anyway )
- Reference< XChild > xChild( xForm->getParent(), UNO_QUERY_THROW );
- Reference< XModel > xDocOwner( xChild->getParent(), UNO_QUERY );
- OSL_TRACE(" Is DOC ????? %s", xDocOwner.is() ? "true" : "false" );
- if ( xDocOwner.is() )
+ do
{
- bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( _nIndex ) );
+ Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
+ if ( !xDoc.is() )
+ break;
+
+ Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
+ Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBACodeNameProvider" ) ), UNO_QUERY );
+ if ( !xNameQuery.is() )
+ break;
+
+ ::osl::MutexGuard aGuard( m_rMutex );
+ bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
if ( hasVBABindings )
- {
- OSL_TRACE("Has VBA bindings already, returning ");
- return;
- }
- Reference< XMultiServiceFactory > xFac( comphelper::getProcessServiceFactory(), UNO_QUERY );
- Reference< XMultiServiceFactory > xDocFac( xDocOwner, UNO_QUERY );
- if ( xFac.is() && xDocFac.is() )
- {
- try
- {
- Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( xFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBAToOOEventDesc" ) ), UNO_QUERY_THROW );
- Reference< XInterface > xIf( getByIndex( _nIndex ) , UNO_QUERY_THROW );
- Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBACodeNameProvider" ) ), UNO_QUERY_THROW );
-
- rtl::OUString sCodeName;
- sCodeName = xNameQuery->getCodeNameForObject( xIf );
- Reference< XPropertySet > xProps( xIf, UNO_QUERY );
- rtl::OUString sServiceName;
- xProps->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl" ) ) >>= sServiceName;
-
- Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( xFac->createInstance( sServiceName ), sCodeName );
- // register the vba script events
- if ( m_xEventAttacher.is() )
- m_xEventAttacher->registerScriptEvents( _nIndex, vbaEvents );
- }
- catch( Exception& ){ OSL_TRACE("lcl_fakevbaevents - Caught Exception trying to create control eventstuff "); }
- }
+ break;
+
+ Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
+ Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
+ if ( xElementAsForm.is() )
+ break;
+ ::rtl::OUString sCodeName( xNameQuery->getCodeNameForObject( xElement ) );
+
+ Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
+ ::rtl::OUString sServiceName;
+ xProps->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl" ) ) >>= sServiceName;
+
+ Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xServiceFactory->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBAToOOEventDesc" ) ), UNO_QUERY_THROW );
+ Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( m_xServiceFactory->createInstance( sServiceName ), sCodeName );
+ // register the vba script events
+ m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
}
+ while ( false );
+ }
+ catch ( const ServiceNotRegisteredException& )
+ {
+ // silence this, not all document types support the ooo.vba.VBACodeNameProvider service
}
- catch( Exception& )
+ catch( const Exception& )
{
+ DBG_UNHANDLED_EXCEPTION();
}
}
@@ -827,8 +827,9 @@ void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _r
void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
{
- RTL_LOGFILE_CONTEXT( aLogger, "forms::OInterfaceContainer::implInsert" );
+ const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
+ // SYNCHRONIZED ----->
::osl::ClearableMutexGuard aGuard( m_rMutex );
::std::auto_ptr< ElementDescription > aAutoDeleteMetaData;
@@ -866,17 +867,24 @@ void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XProper
m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
// announce ourself as parent to the new element
- {
- RTL_LOGFILE_CONTEXT( aLogger, "forms::OInterfaceContainer::implInsert::settingParent" );
- pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
- }
+ pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
// handle the events
- if ( _bEvents && m_xEventAttacher.is() )
+ if ( bHandleEvents )
{
m_xEventAttacher->insertEntry(_nIndex);
m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
- // insert fake events?
+ }
+
+ // notify derived classes
+ implInserted( pElementMetaData );
+
+ aGuard.clear();
+ // <----- SYNCHRONIZED
+
+ // insert faked VBA events?
+ if ( bHandleEvents )
+ {
Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
if ( xMgr.is() )
{
@@ -885,19 +893,16 @@ void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XProper
for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i )
{
// add fake events to the control at index i
- pIfcMgr->fakeVbaEventsHack( i );
+ pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
}
}
else
{
// add fake events to the control at index i
- fakeVbaEventsHack( _nIndex );
+ impl_addVbEvents_nolck_nothrow( _nIndex );
}
}
- // notify derived classes
- implInserted( pElementMetaData );
-
// fire the notification about the change
if ( _bFire )
{
@@ -1187,29 +1192,30 @@ void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) thr
//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException)
{
- OSL_TRACE("*** registerScriptEvent %d", nIndex);
+ ::osl::ClearableMutexGuard aGuard( m_rMutex );
if ( m_xEventAttacher.is() )
{
m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
- fakeVbaEventsHack( nIndex ); // add fake vba events
+ aGuard.clear();
+ impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
}
}
//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException)
{
- OSL_TRACE("*** registerScriptEvent(s) %d", nIndex);
+ ::osl::ClearableMutexGuard aGuard( m_rMutex );
if ( m_xEventAttacher.is() )
{
m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
- fakeVbaEventsHack( nIndex ); // add fake vba events
+ aGuard.clear();
+ impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
}
}
//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException)
{
- OSL_TRACE("*** revokeScriptEvent %d listenertype %s, eventMethod %s", nIndex, rtl::OUStringToOString( aListenerType, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( aEventMethod, RTL_TEXTENCODING_UTF8 ).getStr());
if ( m_xEventAttacher.is() )
m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
}
@@ -1238,7 +1244,6 @@ void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(Illegal
//------------------------------------------------------------------------
Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
{
- OSL_TRACE("getScriptEvents");
Sequence< ScriptEventDescriptor > aReturn;
if ( m_xEventAttacher.is() )
{