Am 06.12.2010 12:32, schrieb Knut Olav Bøhmer:
I will change the patch to make it work for OOo 3.2.1 so you can test it. My
tests with the latest DEV300 version looks very good and I cannot see a
deadlock anymore. Please stay tuned I will send it to you as soon as
possible.

Thank you :)

Hi Knut,

Please look below where I added the content of the patch file. Unfortunately the mailing list removes attachments therefore you have to copy the patch from this mail to a patch file.
The patch applies without a problem on OOO320m19.

Regards,
Carsten

---
diff -urp old/sfx2/inc/sfx2/viewsh.hxx new/sfx2/inc/sfx2/viewsh.hxx
--- old/sfx2/inc/sfx2/viewsh.hxx        2010-03-24 18:53:35.000000000 +0100
+++ new/sfx2/inc/sfx2/viewsh.hxx        2010-12-06 10:57:07.092319976 +0100
@@ -36,6 +36,7 @@
 #include <svtools/lstner.hxx>
 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
 #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
 #include <cppuhelper/interfacecontainer.hxx>
 #include "shell.hxx"
 #include <tools/gen.hxx>
@@ -304,6 +305,7 @@ public:
void SetAdditionalPrintOptions( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& );

void AddRemoveClipboardListener( const com::sun::star::uno::Reference < com::sun::star::datatransfer::clipboard::XClipboardListener>&, BOOL ); + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardNotifier > GetClipboardNotifier();

 #if _SOLAR__PRIVATE
     SAL_DLLPRIVATE SfxInPlaceClient* GetUIActiveIPClient_Impl() const;
diff -urp old/sfx2/source/view/viewsh.cxx new/sfx2/source/view/viewsh.cxx
--- old/sfx2/source/view/viewsh.cxx     2010-03-24 18:53:36.000000000 +0100
+++ new/sfx2/source/view/viewsh.cxx     2010-12-06 13:31:03.663300701 +0100
@@ -44,7 +44,6 @@
 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
 #include <com/sun/star/container/XContainerQuery.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
-#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
 #include <cppuhelper/implbase1.hxx>

@@ -115,7 +114,9 @@ DBG_NAME(SfxViewShell)
 class SfxClipboardChangeListener : public ::cppu::WeakImplHelper1<
        datatransfer::clipboard::XClipboardListener >
 {
-       SfxViewShell* pViewShell;
+public:
+ SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr );
+    virtual ~SfxClipboardChangeListener();

        // XEventListener
        virtual void SAL_CALL disposing( const lang::EventObject& rEventObject )
@@ -125,54 +126,112 @@ class SfxClipboardChangeListener : publi
virtual void SAL_CALL changedContents( const datatransfer::clipboard::ClipboardEvent& rEventObject )
                throw ( uno::RuntimeException );

-public:
-       SfxClipboardChangeListener( SfxViewShell* pView );
-       virtual ~SfxClipboardChangeListener();
+    void DisconnectViewShell() { m_pViewShell = NULL; }
+    void ChangedContents();
+
+    enum AsyncExecuteCmd
+    {
+        ASYNCEXECUTE_CMD_DISPOSING,
+        ASYNCEXECUTE_CMD_CHANGEDCONTENTS
+    };

-    void DisconnectViewShell() { pViewShell = NULL; }
+    struct AsyncExecuteInfo
+    {
+ AsyncExecuteInfo( AsyncExecuteCmd eCmd, uno::Reference< datatransfer::clipboard::XClipboardListener > xThis, SfxClipboardChangeListener* pListener ) :
+            m_eCmd( eCmd ), m_xThis( xThis ), m_pListener( pListener ) {}
+
+        AsyncExecuteCmd m_eCmd;
+ uno::Reference< datatransfer::clipboard::XClipboardListener > m_xThis;
+        SfxClipboardChangeListener* m_pListener;
+    };
+
+private:
+    SfxViewShell* m_pViewShell;
+ uno::Reference< datatransfer::clipboard::XClipboardNotifier > m_xClpbrdNtfr;
+    uno::Reference< lang::XComponent > m_xCtrl;
+
+ DECL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo* );
 };

-SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell* pView )
-: pViewShell( 0 )
+SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr )
+    : m_pViewShell( 0 ), m_xClpbrdNtfr( xClpbrdNtfr )
 {
- uno::Reference < lang::XComponent > xCtrl( pView->GetController(), uno::UNO_QUERY );
-       if ( xCtrl.is() )
-       {
- xCtrl->addEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) );
-               pViewShell = pView;
-       }
+ m_xCtrl = uno::Reference < lang::XComponent >( pView->GetController(), uno::UNO_QUERY );
+    if ( m_xCtrl.is() )
+    {
+ m_xCtrl->addEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) );
+        m_pViewShell = pView;
+    }
+    if ( m_xClpbrdNtfr.is() )
+    {
+ m_xClpbrdNtfr->addClipboardListener( uno::Reference< datatransfer::clipboard::XClipboardListener >( + static_cast< datatransfer::clipboard::XClipboardListener* >( this )));
+    }
 }

 SfxClipboardChangeListener::~SfxClipboardChangeListener()
 {
 }

+void SfxClipboardChangeListener::ChangedContents()
+{
+    const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+    if( m_pViewShell )
+    {
+        SfxBindings& rBind = m_pViewShell->GetViewFrame()->GetBindings();
+        rBind.Invalidate( SID_PASTE );
+        rBind.Invalidate( SID_PASTE_SPECIAL );
+        rBind.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
+    }
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo*, pAsyncExecuteInfo )
+{
+    if ( pAsyncExecuteInfo )
+    {
+ uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( pAsyncExecuteInfo->m_xThis );
+        if ( pAsyncExecuteInfo->m_pListener )
+        {
+            if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_DISPOSING )
+                pAsyncExecuteInfo->m_pListener->DisconnectViewShell();
+ else if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_CHANGEDCONTENTS )
+                pAsyncExecuteInfo->m_pListener->ChangedContents();
+        }
+    }
+    delete pAsyncExecuteInfo;
+
+    return 0;
+}
+
void SAL_CALL SfxClipboardChangeListener::disposing( const lang::EventObject& /*rEventObject*/ )
 throw ( uno::RuntimeException )
 {
- // either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore
-    const ::vos::OGuard aGuard( Application::GetSolarMutex() );
-       if ( pViewShell )
-       {
- uno::Reference < lang::XComponent > xCtrl( pViewShell->GetController(), uno::UNO_QUERY );
-               if ( xCtrl.is() )
- xCtrl->removeEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) ); - pViewShell->AddRemoveClipboardListener( uno::Reference < datatransfer::clipboard::XClipboardListener > (this), FALSE );
-               pViewShell = 0;
-       }
+ // Either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore
+    uno::Reference< lang::XComponent > xCtrl( m_xCtrl );
+ uno::Reference< datatransfer::clipboard::XClipboardNotifier > xNotify( m_xClpbrdNtfr );
+
+ uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this ));
+    if ( xCtrl.is() )
+ xCtrl->removeEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this )));
+    if ( xNotify.is() )
+        xNotify->removeClipboardListener( xThis );
+
+    // Make asynchronous call to avoid locking SolarMutex which is the
+    // root for many deadlocks, especially in conjuction with the "Windows"
+    // based single thread apartment clipboard code!
+ AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_DISPOSING, xThis, this ); + Application::PostUserEvent( STATIC_LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo );
 }

void SAL_CALL SfxClipboardChangeListener::changedContents( const datatransfer::clipboard::ClipboardEvent& )
        throw ( RuntimeException )
 {
-    const ::vos::OGuard aGuard( Application::GetSolarMutex() );
-    if( pViewShell )
-       {
-               SfxBindings& rBind = pViewShell->GetViewFrame()->GetBindings();
-               rBind.Invalidate( SID_PASTE );
-        rBind.Invalidate( SID_PASTE_SPECIAL );
-        rBind.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
-       }
+    // Make asynchronous call to avoid locking SolarMutex which is the
+    // root for many deadlocks, especially in conjuction with the "Windows"
+    // based single thread apartment clipboard code!
+ uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this )); + AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_CHANGEDCONTENTS, xThis, this ); + Application::PostUserEvent( STATIC_LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo );
 }


@@ -2011,8 +2070,7 @@ void SfxViewShell::SetController( SfxBas
     if (  pImp->xClipboardListener.is() )
         pImp->xClipboardListener->DisconnectViewShell();

-    pImp->xClipboardListener = new SfxClipboardChangeListener( this );
-       AddRemoveClipboardListener( pImp->xClipboardListener.get(), TRUE );
+ pImp->xClipboardListener = new SfxClipboardChangeListener( this, GetClipboardNotifier() );
 }

 Reference < XController > SfxViewShell::GetController()
@@ -2216,6 +2274,15 @@ BOOL SfxViewShell::Escape()
return GetViewFrame()->GetBindings().Execute( SID_TERMINATE_INPLACEACTIVATION );
 }

+uno::Reference< datatransfer::clipboard::XClipboardNotifier > SfxViewShell::GetClipboardNotifier()
+{
+ uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClipboardNotifier;
+    if ( GetViewFrame() )
+ xClipboardNotifier = uno::Reference< datatransfer::clipboard::XClipboardNotifier >( GetViewFrame()->GetWindow().GetClipboard(), uno::UNO_QUERY );
+
+    return xClipboardNotifier;
+}
+
void SfxViewShell::AddRemoveClipboardListener( const uno::Reference < datatransfer::clipboard::XClipboardListener >& rClp, BOOL bAdd )
 {
     try


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to