diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-06-22 08:02:46 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-06-22 07:07:40 +0000 |
commit | 380a646b957052f96b3f9440d20dc63fc72e1d46 (patch) | |
tree | 50deed3cbb91531d60f21cf2173a45f3bff44e3c | |
parent | b4861b60b2f6d7ffd9efcd8e028e2578da4b464f (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>
-rw-r--r-- | libreofficekit/source/gtk/lokdocview.cxx | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index 1d629b9a6515..5510cde2b710 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()); @@ -842,6 +847,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()); @@ -851,6 +857,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; @@ -1733,6 +1740,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()); @@ -1758,6 +1766,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]) @@ -1832,6 +1841,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()); @@ -1855,6 +1865,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, @@ -1870,6 +1881,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()); @@ -1898,6 +1910,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 ); @@ -1927,11 +1940,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); } @@ -1945,6 +1960,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()); @@ -1967,6 +1983,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()); @@ -1986,6 +2003,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()); @@ -2036,6 +2054,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()); @@ -2055,6 +2074,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"; @@ -2935,6 +2955,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()); @@ -2949,6 +2970,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()); @@ -2992,6 +3014,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()); |