summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-06-22 08:02:46 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-07-20 17:16:26 +0200
commit3e9dad4e65aed149a2590d6ec05c407eb99d4c6b (patch)
tree64a3fa855a1ef5d4a2d1887d472d717a3efb9c68
parent16382e0c6779305a7460b4182612e4e59561ef6b (diff)
lokdocview: ensure setView() + doSomethingElse is atomic
Otherwise it's possible that a keystroke is sent in for a different view, when that other view reacts to an invalidation (invoking paintTile()) caused by a previous keystroke. I.e. open two views, place the cursor at different positions, type fast, and some of the characters appeared at the incorrect view. Change-Id: Ie5e471f1b9c2d69adaa87111fba74d4abe184ef8 Reviewed-on: https://gerrit.libreoffice.org/26562 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit 380a646b957052f96b3f9440d20dc63fc72e1d46)
-rw-r--r--libreofficekit/source/gtk/lokdocview.cxx23
1 files changed, 23 insertions, 0 deletions
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 60e22fc49596..6e2a3439c771 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -15,6 +15,7 @@
#include <string>
#include <sstream>
#include <iostream>
+#include <mutex>
#include <boost/property_tree/json_parser.hpp>
#include <com/sun/star/awt/Key.hpp>
@@ -44,6 +45,9 @@
// Minimum Zoom allowed
#define MIN_ZOOM 0.25f
+/// This is expected to be locked during setView(), doSomethingElse() LOK calls.
+std::mutex g_aLOKMutex;
+
/// Private struct used by this GObject type
struct LOKDocViewPrivateImpl
{
@@ -581,6 +585,7 @@ postKeyEventInThread(gpointer data)
LOKDocViewPrivate& priv = getPrivate(pDocView);
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -836,6 +841,7 @@ static gboolean postDocumentLoad(gpointer pData)
LOKDocView* pLOKDocView = static_cast<LOKDocView*>(pData);
LOKDocViewPrivate& priv = getPrivate(pLOKDocView);
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -845,6 +851,7 @@ static gboolean postDocumentLoad(gpointer pData)
priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pLOKDocView);
priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips);
priv->m_nParts = priv->m_pDocument->pClass->getParts(priv->m_pDocument);
+ aGuard.unlock();
g_timeout_add(600, handleTimeout, pLOKDocView);
float zoom = priv->m_fZoom;
@@ -1727,6 +1734,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
GdkPoint aPoint;
GError* error = nullptr;
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -1752,6 +1760,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
priv->m_pDocument->pClass->setTextSelection(priv->m_pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x, priv->m_fZoom), pixelToTwip(aPoint.y, priv->m_fZoom));
return FALSE;
}
+ aGuard.unlock();
for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
{
if (priv->m_bInDragGraphicHandles[i])
@@ -1826,6 +1835,7 @@ setGraphicSelectionInThread(gpointer data)
LOKDocViewPrivate& priv = getPrivate(pDocView);
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+ std::lock_guard<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -1849,6 +1859,7 @@ setClientZoomInThread(gpointer data)
LOKDocViewPrivate& priv = getPrivate(pDocView);
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+ std::lock_guard<std::mutex> aGuard(g_aLOKMutex);
priv->m_pDocument->pClass->setClientZoom(priv->m_pDocument,
pLOEvent->m_nTilePixelWidth,
pLOEvent->m_nTilePixelHeight,
@@ -1864,6 +1875,7 @@ postMouseEventInThread(gpointer data)
LOKDocViewPrivate& priv = getPrivate(pDocView);
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+ std::lock_guard<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -1892,6 +1904,7 @@ openDocumentInThread (gpointer data)
LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
LOKDocViewPrivate& priv = getPrivate(pDocView);
+ std::lock_guard<std::mutex> aGuard(g_aLOKMutex);
if ( priv->m_pDocument )
{
priv->m_pDocument->pClass->destroy( priv->m_pDocument );
@@ -1921,11 +1934,13 @@ setPartInThread(gpointer data)
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
int nPart = pLOEvent->m_nPart;
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart );
+ aGuard.unlock();
lok_doc_view_reset_view(pDocView);
}
@@ -1939,6 +1954,7 @@ setPartmodeInThread(gpointer data)
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
int nPartMode = pLOEvent->m_nPartMode;
+ std::lock_guard<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -1961,6 +1977,7 @@ setEditInThread(gpointer data)
else if (priv->m_bEdit && !bEdit)
{
g_info("lok_doc_view_set_edit: leaving edit mode");
+ std::lock_guard<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -1980,6 +1997,7 @@ postCommandInThread (gpointer data)
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
LOKDocViewPrivate& priv = getPrivate(pDocView);
+ std::lock_guard<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -2030,6 +2048,7 @@ paintTileInThread (gpointer data)
aTileRectangle.x = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileY;
aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileX;
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -2049,6 +2068,7 @@ paintTileInThread (gpointer data)
aTileRectangle.x, aTileRectangle.y,
pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom),
pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom));
+ aGuard.unlock();
g_timer_elapsed(aTimer, &nElapsedMs);
ss << " rendered in " << (nElapsedMs / 1000.) << " milliseconds";
@@ -2929,6 +2949,7 @@ lok_doc_view_get_parts (LOKDocView* pDocView)
if (!priv->m_pDocument)
return -1;
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -2943,6 +2964,7 @@ lok_doc_view_get_part (LOKDocView* pDocView)
if (!priv->m_pDocument)
return -1;
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());
@@ -2986,6 +3008,7 @@ lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart)
if (!priv->m_pDocument)
return nullptr;
+ std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
std::stringstream ss;
ss << "lok::Document::setView(" << priv->m_nViewId << ")";
g_info("%s", ss.str().c_str());