diff options
Diffstat (limited to 'dtrans/source/win32/dtobj/XTDataObject.cxx')
-rw-r--r-- | dtrans/source/win32/dtobj/XTDataObject.cxx | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/dtrans/source/win32/dtobj/XTDataObject.cxx b/dtrans/source/win32/dtobj/XTDataObject.cxx index 3ca9325a2d3c..1c13d346aa5a 100644 --- a/dtrans/source/win32/dtobj/XTDataObject.cxx +++ b/dtrans/source/win32/dtobj/XTDataObject.cxx @@ -25,8 +25,11 @@ #include "DTransHelper.hxx" #include "TxtCnvtHlp.hxx" #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#include "com/sun/star/awt/AsyncCallback.hpp" +#include "com/sun/star/awt/XCallback.hpp" #include "FmtFilter.hxx" #include <comphelper/processfactory.hxx> +#include <cppuhelper/implbase.hxx> #if defined _MSC_VER #pragma warning(push,1) @@ -82,6 +85,28 @@ void SAL_CALL setupStgMedium( const FORMATETC& fetc, OSL_ASSERT( false ); } +/** + We need to destroy XTransferable in the main thread to avoid dead lock + when locking in the clipboard thread. So we transfer the ownership of the + XTransferable reference to this object and release it when the callback + is executed in main thread. +*/ +class AsyncDereference : public cppu::WeakImplHelper<css::awt::XCallback> +{ + Reference<XTransferable> maTransferable; + +public: + AsyncDereference(css::uno::Reference<css::datatransfer::XTransferable> const & rTransferable) + : maTransferable(rTransferable) + {} + + virtual void SAL_CALL notify(css::uno::Any const &) + throw (css::uno::RuntimeException, std::exception) override + { + maTransferable.set(nullptr); + } +}; + // a helper class that will be thrown by the function validateFormatEtc class CInvalidFormatEtcException @@ -174,12 +199,20 @@ CXTDataObject::CXTDataObject( const Reference< XComponentContext >& rxContext, const Reference< XTransferable >& aXTransferable ) : m_nRefCnt( 0 ) , m_XTransferable( aXTransferable ) + , m_XComponentContext( rxContext ) , m_bFormatEtcContainerInitialized( false ) , m_DataFormatTranslator( rxContext ) , m_FormatRegistrar( rxContext, m_DataFormatTranslator ) { } +CXTDataObject::~CXTDataObject() +{ + css::awt::AsyncCallback::create(m_XComponentContext)->addCallback( + new AsyncDereference(m_XTransferable), + css::uno::Any()); +} + // IUnknown->QueryInterface STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject ) |