summaryrefslogtreecommitdiff
path: root/dtrans/source/win32/dtobj/XTDataObject.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dtrans/source/win32/dtobj/XTDataObject.cxx')
-rw-r--r--dtrans/source/win32/dtobj/XTDataObject.cxx33
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 )