drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx  |   22 
+++++-----
 drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx        |    4 -
 drawinglayer/source/primitive2d/controlprimitive2d.cxx                |    4 -
 drawinglayer/source/primitive2d/gridprimitive2d.cxx                   |    4 -
 drawinglayer/source/primitive2d/helplineprimitive2d.cxx               |    4 -
 drawinglayer/source/primitive2d/polygonprimitive2d.cxx                |    4 -
 drawinglayer/source/primitive2d/primitivetools2d.cxx                  |   18 
++++----
 drawinglayer/source/primitive2d/sceneprimitive2d.cxx                  |    4 -
 drawinglayer/source/primitive2d/texteffectprimitive2d.cxx             |    4 -
 include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx |    2 
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx                  |    4 -
 svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx              |    2 
 svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx                     |    4 -
 13 files changed, 42 insertions(+), 38 deletions(-)

New commits:
commit 303e5631f8119ef69c8ff515e7e47d4cf6ab74c6
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Mar 14 11:50:51 2025 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Fri Mar 14 12:47:18 2025 +0100

    use mutex before touching maBuffered2DDecomposition (tdf#131595 related)
    
    Otherwise we could be reading stale data.
    
    And change it to return a bool, the call-sites only care if we
    have/dont-have the data, and returning a value of a field that should only
    be accessed under a lock is dodgy.
    
    And move the the setRemainingTime call to get2DDecomposition(), because
    that where we really "use" the data ie. paint with it.
    
    Change-Id: I44b5d41fee68985213ecc7d11b4ce1bdcfd119b3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182909
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git 
a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
index ba8a4606cc83..b04905744b50 100644
--- a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
@@ -58,15 +58,15 @@ void 
flushBufferedDecomposition(BufferedDecompositionPrimitive2D& rTarget)
     rTarget.release();
 }
 
-const Primitive2DReference& 
BufferedDecompositionPrimitive2D::getBuffered2DDecomposition() const
+bool BufferedDecompositionPrimitive2D::hasBuffered2DDecomposition() const
 {
-    if (0 != maCallbackSeconds && maCallbackTimer.is())
+    if (0 != maCallbackSeconds)
     {
-        // decomposition was used, touch/restart time
-        
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
+        std::lock_guard Guard(maCallbackLock);
+        return maBuffered2DDecomposition.is();
     }
-
-    return maBuffered2DDecomposition;
+    else
+        return maBuffered2DDecomposition.is();
 }
 
 void 
BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DReference
 rNew)
@@ -128,7 +128,7 @@ void BufferedDecompositionPrimitive2D::get2DDecomposition(
     Primitive2DDecompositionVisitor& rVisitor,
     const geometry::ViewInformation2D& rViewInformation) const
 {
-    if (!getBuffered2DDecomposition())
+    if (!hasBuffered2DDecomposition())
     {
         Primitive2DReference aNew = create2DDecomposition(rViewInformation);
         
const_cast<BufferedDecompositionPrimitive2D*>(this)->setBuffered2DDecomposition(
@@ -138,15 +138,19 @@ void BufferedDecompositionPrimitive2D::get2DDecomposition(
     if (0 == maCallbackSeconds)
     {
         // no flush/multithreading is in use, just call
-        rVisitor.visit(getBuffered2DDecomposition());
+        rVisitor.visit(maBuffered2DDecomposition);
         return;
     }
 
+    // decomposition was used, touch/restart time
+    if (maCallbackTimer)
+        
maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
+
     // tdf#158913 need to secure 'visit' when flush/multithreading is in use,
     // so that the local non-ref-Counted instance of the decomposition gets not
     // manipulated (e.g. deleted)
     std::lock_guard Guard(maCallbackLock);
-    rVisitor.visit(getBuffered2DDecomposition());
+    rVisitor.visit(maBuffered2DDecomposition);
 }
 
 } // end of namespace drawinglayer::primitive2d
diff --git a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx 
b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
index a155e6472e24..7d73cdbee4d1 100644
--- a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
@@ -87,13 +87,13 @@ namespace drawinglayer::primitive2d
 
         void 
BackgroundColorPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& 
rVisitor, const geometry::ViewInformation2D& rViewInformation) const
         {
-            if(getBuffered2DDecomposition() && (maLastViewport != 
rViewInformation.getViewport()))
+            if(hasBuffered2DDecomposition() && (maLastViewport != 
rViewInformation.getViewport()))
             {
                 // conditions of last local decomposition have changed, delete
                 const_cast< BackgroundColorPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember ViewRange
                 const_cast< BackgroundColorPrimitive2D* 
>(this)->maLastViewport = rViewInformation.getViewport();
diff --git a/drawinglayer/source/primitive2d/controlprimitive2d.cxx 
b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
index eb8759bb2169..81af256a88bb 100644
--- a/drawinglayer/source/primitive2d/controlprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
@@ -333,7 +333,7 @@ namespace drawinglayer::primitive2d
             // destroy existing decomposition. To detect change, use size of 
unit size in view coordinates
             const basegfx::B2DVector 
aNewScaling(rViewInformation.getObjectToViewTransformation() * 
basegfx::B2DVector(1.0, 1.0));
 
-            if(getBuffered2DDecomposition())
+            if(hasBuffered2DDecomposition())
             {
                 if(!maLastViewScaling.equal(aNewScaling))
                 {
@@ -342,7 +342,7 @@ namespace drawinglayer::primitive2d
                 }
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember ViewTransformation
                 const_cast< ControlPrimitive2D* >(this)->maLastViewScaling = 
aNewScaling;
diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx 
b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
index 1a996188f03c..80bc56e2250c 100644
--- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
@@ -309,7 +309,7 @@ namespace drawinglayer::primitive2d
 
         void 
GridPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, 
const geometry::ViewInformation2D& rViewInformation) const
         {
-            if(getBuffered2DDecomposition())
+            if(hasBuffered2DDecomposition())
             {
                 if(maLastViewport != rViewInformation.getViewport() || 
maLastObjectToViewTransformation != 
rViewInformation.getObjectToViewTransformation())
                 {
@@ -318,7 +318,7 @@ namespace drawinglayer::primitive2d
                 }
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember ViewRange and ViewTransformation
                 const_cast< GridPrimitive2D* 
>(this)->maLastObjectToViewTransformation = 
rViewInformation.getObjectToViewTransformation();
diff --git a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx 
b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
index 047084eb1469..e09c4db606d0 100644
--- a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
@@ -159,7 +159,7 @@ namespace drawinglayer::primitive2d
 
         void 
HelplinePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& 
rVisitor, const geometry::ViewInformation2D& rViewInformation) const
         {
-            if(getBuffered2DDecomposition())
+            if(hasBuffered2DDecomposition())
             {
                 if(maLastViewport != rViewInformation.getViewport() || 
maLastObjectToViewTransformation != 
rViewInformation.getObjectToViewTransformation())
                 {
@@ -168,7 +168,7 @@ namespace drawinglayer::primitive2d
                 }
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember ViewRange and ViewTransformation
                 const_cast< HelplinePrimitive2D* 
>(this)->maLastObjectToViewTransformation = 
rViewInformation.getObjectToViewTransformation();
diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx 
b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
index 77800ed45417..329911541d4e 100644
--- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
@@ -298,7 +298,7 @@ void PolygonMarkerPrimitive2D::get2DDecomposition(
 {
     bool bNeedNewDecomposition(false);
 
-    if (getBuffered2DDecomposition())
+    if (hasBuffered2DDecomposition())
     {
         if (rViewInformation.getInverseObjectToViewTransformation()
             != maLastInverseObjectToViewTransformation)
@@ -313,7 +313,7 @@ void PolygonMarkerPrimitive2D::get2DDecomposition(
         
const_cast<PolygonMarkerPrimitive2D*>(this)->setBuffered2DDecomposition(nullptr);
     }
 
-    if (!getBuffered2DDecomposition())
+    if (!hasBuffered2DDecomposition())
     {
         // remember last used InverseObjectToViewTransformation
         PolygonMarkerPrimitive2D* pThat = 
const_cast<PolygonMarkerPrimitive2D*>(this);
diff --git a/drawinglayer/source/primitive2d/primitivetools2d.cxx 
b/drawinglayer/source/primitive2d/primitivetools2d.cxx
index 04a91fe9b55b..cf98fd9b26c0 100644
--- a/drawinglayer/source/primitive2d/primitivetools2d.cxx
+++ b/drawinglayer/source/primitive2d/primitivetools2d.cxx
@@ -30,13 +30,13 @@ namespace drawinglayer::primitive2d
             const basegfx::B2DVector 
aDiscreteVector(rViewInformation.getInverseObjectToViewTransformation() * 
basegfx::B2DVector(1.0, 1.0));
             const double fDiscreteUnit(std::min(fabs(aDiscreteVector.getX()), 
fabs(aDiscreteVector.getY())));
 
-            if(getBuffered2DDecomposition() && 
!basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit()))
+            if(hasBuffered2DDecomposition() && 
!basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit()))
             {
                 // conditions of last local decomposition have changed, delete
                 const_cast< DiscreteMetricDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember new valid DiscreteUnit
                 const_cast< DiscreteMetricDependentPrimitive2D* 
>(this)->mfDiscreteUnit = fDiscreteUnit;
@@ -54,13 +54,13 @@ namespace drawinglayer::primitive2d
             // get the current Viewport
             const basegfx::B2DRange& rViewport = 
rViewInformation.getViewport();
 
-            if(getBuffered2DDecomposition() && !rViewport.equal(getViewport()))
+            if(hasBuffered2DDecomposition() && !rViewport.equal(getViewport()))
             {
                 // conditions of last local decomposition have changed, delete
                 const_cast< ViewportDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember new valid DiscreteUnit
                 const_cast< ViewportDependentPrimitive2D* >(this)->maViewport 
= rViewport;
@@ -75,13 +75,13 @@ namespace drawinglayer::primitive2d
             // get the current ViewTransformation
             const basegfx::B2DHomMatrix& rViewTransformation = 
rViewInformation.getViewTransformation();
 
-            if(getBuffered2DDecomposition() && rViewTransformation != 
getViewTransformation())
+            if(hasBuffered2DDecomposition() && rViewTransformation != 
getViewTransformation())
             {
                 // conditions of last local decomposition have changed, delete
                 const_cast< ViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember new valid ViewTransformation
                 const_cast< ViewTransformationDependentPrimitive2D* 
>(this)->maViewTransformation = rViewTransformation;
@@ -96,7 +96,7 @@ namespace drawinglayer::primitive2d
             // get the current ViewTransformation
             const basegfx::B2DHomMatrix& rViewTransformation = 
rViewInformation.getViewTransformation();
 
-            if(getBuffered2DDecomposition() && rViewTransformation != 
getViewTransformation())
+            if(hasBuffered2DDecomposition() && rViewTransformation != 
getViewTransformation())
             {
                 // conditions of last local decomposition have changed, delete
                 const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
@@ -105,13 +105,13 @@ namespace drawinglayer::primitive2d
             // get the current ObjectTransformation
             const basegfx::B2DHomMatrix& rObjectTransformation = 
rViewInformation.getObjectTransformation();
 
-            if(getBuffered2DDecomposition() && rObjectTransformation != 
getObjectTransformation())
+            if(hasBuffered2DDecomposition() && rObjectTransformation != 
getObjectTransformation())
             {
                 // conditions of last local decomposition have changed, delete
                 const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 // remember new valid ViewTransformation, and 
ObjectTransformation
                 const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->maViewTransformation = rViewTransformation;
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx 
b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
index 11807e459b7f..5300e8d82e05 100644
--- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -687,7 +687,7 @@ namespace drawinglayer::primitive2d
             bool bNeedNewDecomposition(false);
             bool bDiscreteSizesAreCalculated(false);
 
-            if(getBuffered2DDecomposition())
+            if(hasBuffered2DDecomposition())
             {
                 basegfx::B2DRange aVisibleDiscreteRange;
                 calculateDiscreteSizes(rViewInformation, aDiscreteRange, 
aVisibleDiscreteRange, aUnitVisibleRange);
@@ -718,7 +718,7 @@ namespace drawinglayer::primitive2d
                 const_cast< ScenePrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 if(!bDiscreteSizesAreCalculated)
                 {
diff --git a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx 
b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
index bd123d34315d..e1893ec0fd38 100644
--- a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
@@ -214,7 +214,7 @@ void TextEffectPrimitive2D::get2DDecomposition(
     Primitive2DDecompositionVisitor& rVisitor,
     const geometry::ViewInformation2D& rViewInformation) const
 {
-    if (getBuffered2DDecomposition())
+    if (hasBuffered2DDecomposition())
     {
         if (maLastObjectToViewTransformation != 
rViewInformation.getObjectToViewTransformation())
         {
@@ -223,7 +223,7 @@ void TextEffectPrimitive2D::get2DDecomposition(
         }
     }
 
-    if (!getBuffered2DDecomposition())
+    if (!hasBuffered2DDecomposition())
     {
         // remember ViewRange and ViewTransformation
         
const_cast<TextEffectPrimitive2D*>(this)->maLastObjectToViewTransformation
diff --git 
a/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx 
b/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
index 427c6d4c19f7..3fbfb1e1e00c 100644
--- a/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
+++ b/include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
@@ -79,7 +79,7 @@ protected:
         later thread-safe stuff to be added if needed. Only to be used by 
getDecomposition()
         implementations for buffering the last decomposition.
      */
-    const Primitive2DReference& getBuffered2DDecomposition() const;
+    bool hasBuffered2DDecomposition() const;
     void setBuffered2DDecomposition(Primitive2DReference rNew);
 
     /** method which is to be used to implement the local decomposition of a 
2D primitive. */
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx 
b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index 617dcba30631..78daae6c4c5e 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -322,7 +322,7 @@ void SlideBackgroundFillPrimitive2D::get2DDecomposition(
     basegfx::B2DVector aPageSize;
     drawinglayer::attribute::SdrFillAttribute aFill;
 
-    if(getBuffered2DDecomposition())
+    if(hasBuffered2DDecomposition())
     {
         aFill = getMasterPageFillAttribute(rViewInformation, aPageSize);
 
@@ -333,7 +333,7 @@ void SlideBackgroundFillPrimitive2D::get2DDecomposition(
         }
     }
 
-    if(!getBuffered2DDecomposition())
+    if(!hasBuffered2DDecomposition())
     {
         // remember last Fill
         const_cast< SlideBackgroundFillPrimitive2D* >(this)->maLastFill = 
std::move(aFill);
diff --git a/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx 
b/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx
index 9e34a385ba9e..bdf7b520f025 100644
--- a/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx
@@ -896,7 +896,7 @@ namespace drawinglayer::primitive2d
                 {
                     // conditions of last local decomposition have changed, 
delete
                     // possible content
-                    if(getBuffered2DDecomposition())
+                    if(hasBuffered2DDecomposition())
                     {
                         const_cast< SdrFrameBorderPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
                     }
diff --git a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx 
b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx
index 516103aaccfd..cc1e850ccb68 100644
--- a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx
@@ -144,7 +144,7 @@ namespace drawinglayer::primitive2d
             sal_Int16 nCurrentlyValidPageNumber(0);
             sal_Int16 nCurrentlyValidPageCount(0);
 
-            if(getBuffered2DDecomposition())
+            if(hasBuffered2DDecomposition())
             {
                 bool bDoDelete(false);
 
@@ -202,7 +202,7 @@ namespace drawinglayer::primitive2d
                 }
             }
 
-            if(!getBuffered2DDecomposition())
+            if(!hasBuffered2DDecomposition())
             {
                 if(!bCurrentlyVisualizingPageIsSet && mbContainsPageField)
                 {

Reply via email to