summaryrefslogtreecommitdiff
path: root/vcl/unx
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2019-01-29 18:39:25 +0100
committerMichael Stahl <Michael.Stahl@cib.de>2019-01-30 14:40:56 +0100
commit9286cebdff378a19ec146183676c6da96aac77db (patch)
tree7afde4e856225614e1e31e79bfe59062a6a5e70f /vcl/unx
parentb9afe593d4756ea30a9f23af6f5f0414656173f0 (diff)
vcl: fix deadlock in VclGtkClipboard::setContents()
Must not call getTransferDataFlavors with m_Mutex held; 6 TransferableHelper::getTransferDataFlavors() (this=0x567b980) at svtools/source/misc/transfer.cxx:392 7 VclGtkClipboard::setContents(com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> const&, com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboardOwner> const&) (this=0x3199550, xTrans=uno::Reference to (SwTransferable *) 0x567b9a8, xClipboardOwner=uno::Reference to (SwTransferable *) 0x567b9b0) at vcl/unx/gtk3_kde5/../gtk3/gtk3gtkinst.cxx:618 8 TransferableHelper::CopyToSelection(vcl::Window*) const (this=0x567b980, pWindow=0x301b0c0) at svtools/source/misc/transfer.cxx:960 CopyToSelection() uses SolarMutexReleaser, then getTransferDataFlavors() has a SolarMutexGuard; this will deadlock against the main thread that holds SolarMutex and calls VclGtkClipboard::setContents() itself, from VclGtkClipboard::OwnerPossiblyChanged(). Change-Id: Ibda0b6bce6f3388c45cee8077dd977abb3dda366 Reviewed-on: https://gerrit.libreoffice.org/67121 Tested-by: Jenkins Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
Diffstat (limited to 'vcl/unx')
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx7
1 files changed, 6 insertions, 1 deletions
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 9365b2a30776..93045d9e7197 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -617,6 +617,12 @@ void VclGtkClipboard::setContents(
const Reference< css::datatransfer::XTransferable >& xTrans,
const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner )
{
+ css::uno::Sequence<css::datatransfer::DataFlavor> aFormats;
+ if (xTrans.is())
+ {
+ aFormats = xTrans->getTransferDataFlavors();
+ }
+
osl::ClearableMutexGuard aGuard( m_aMutex );
Reference< datatransfer::clipboard::XClipboardOwner > xOldOwner( m_aOwner );
Reference< datatransfer::XTransferable > xOldContents( m_aContents );
@@ -635,7 +641,6 @@ void VclGtkClipboard::setContents(
assert(m_aGtkTargets.empty());
if (m_aContents.is())
{
- css::uno::Sequence<css::datatransfer::DataFlavor> aFormats = xTrans->getTransferDataFlavors();
std::vector<GtkTargetEntry> aGtkTargets(m_aConversionHelper.FormatsToGtk(aFormats));
if (!aGtkTargets.empty())
{