Re: Re: Debugging Hanging OOo

Carsten Driesner <[email protected]>
Newsgroups gmane.comp.openoffice.devel.general
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.