drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx  |   
25 ++++++----
 drawinglayer/source/primitive2d/glowprimitive2d.cxx                        |   
 6 +-
 drawinglayer/source/primitive2d/shadowprimitive2d.cxx                      |   
 6 +-
 drawinglayer/source/primitive2d/softedgeprimitive2d.cxx                    |   
 6 +-
 include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx |   
 2 
 5 files changed, 25 insertions(+), 20 deletions(-)

New commits:
commit ab4cf371eda16668b875dbd99950034b09d0dc4c
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Mar 14 11:36:30 2025 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Fri Mar 14 12:27:17 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: Ie795465a1177a47f846cf9310d419079e52b8770
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182908
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git 
a/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx
index 4a09d0490ce9..fcdbe8d02d78 100644
--- a/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx
@@ -58,16 +58,17 @@ void 
flushBufferedDecomposition(BufferedDecompositionGroupPrimitive2D& rTarget)
     rTarget.release();
 }
 
-const Primitive2DContainer&
-BufferedDecompositionGroupPrimitive2D::getBuffered2DDecomposition() const
+bool BufferedDecompositionGroupPrimitive2D::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.empty();
+    }
+    else
+    {
+        return !maBuffered2DDecomposition.empty();
     }
-
-    return maBuffered2DDecomposition;
 }
 
 void 
BufferedDecompositionGroupPrimitive2D::setBuffered2DDecomposition(Primitive2DContainer&&
 rNew)
@@ -130,7 +131,7 @@ void 
BufferedDecompositionGroupPrimitive2D::get2DDecomposition(
     Primitive2DDecompositionVisitor& rVisitor,
     const geometry::ViewInformation2D& rViewInformation) const
 {
-    if (getBuffered2DDecomposition().empty())
+    if (!hasBuffered2DDecomposition())
     {
         Primitive2DContainer aNewSequence;
         create2DDecomposition(aNewSequence, rViewInformation);
@@ -141,15 +142,19 @@ void 
BufferedDecompositionGroupPrimitive2D::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/glowprimitive2d.cxx 
b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
index 18fa5224887d..ed212ae4da6d 100644
--- a/drawinglayer/source/primitive2d/glowprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
@@ -261,7 +261,7 @@ void 
GlowPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisit
                                        fDiscreteGlowRadius, rViewInformation))
         return;
 
-    if (!getBuffered2DDecomposition().empty())
+    if (hasBuffered2DDecomposition())
     {
         // First check is to detect if the last created decompose is capable
         // to represent the now requested visualization.
@@ -295,7 +295,7 @@ void 
GlowPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisit
         }
     }
 
-    if (!getBuffered2DDecomposition().empty())
+    if (hasBuffered2DDecomposition())
     {
         // Second check is to react on changes of the DiscreteGlowRadius when
         // zooming in/out.
@@ -324,7 +324,7 @@ void 
GlowPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisit
         }
     }
 
-    if (getBuffered2DDecomposition().empty())
+    if (!hasBuffered2DDecomposition())
     {
         // refresh last used DiscreteGlowRadius and ClippedRange to new 
remembered values
         const_cast<GlowPrimitive2D*>(this)->mfLastDiscreteGlowRadius = 
fDiscreteGlowRadius;
diff --git a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx 
b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
index c6a7a2e66707..ff5600d1f5cf 100644
--- a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
@@ -313,7 +313,7 @@ void ShadowPrimitive2D::get2DDecomposition(
                                        fDiscreteBlurRadius, rViewInformation))
         return;
 
-    if (!getBuffered2DDecomposition().empty())
+    if (hasBuffered2DDecomposition())
     {
         // First check is to detect if the last created decompose is capable
         // to represent the now requested visualization (see similar
@@ -340,7 +340,7 @@ void ShadowPrimitive2D::get2DDecomposition(
         }
     }
 
-    if (!getBuffered2DDecomposition().empty())
+    if (hasBuffered2DDecomposition())
     {
         // Second check is to react on changes of the DiscreteSoftRadius when
         // zooming in/out (see similar implementation at ShadowPrimitive2D).
@@ -365,7 +365,7 @@ void ShadowPrimitive2D::get2DDecomposition(
         }
     }
 
-    if (getBuffered2DDecomposition().empty())
+    if (!hasBuffered2DDecomposition())
     {
         // refresh last used DiscreteBlurRadius and ClippedRange to new 
remembered values
         const_cast<ShadowPrimitive2D*>(this)->mfLastDiscreteBlurRadius = 
fDiscreteBlurRadius;
diff --git a/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx 
b/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx
index e6f92f312f59..df05771f27a6 100644
--- a/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/softedgeprimitive2d.cxx
@@ -268,7 +268,7 @@ void SoftEdgePrimitive2D::get2DDecomposition(
                                            fDiscreteSoftRadius, 
rViewInformation))
             break;
 
-        if (!getBuffered2DDecomposition().empty())
+        if (hasBuffered2DDecomposition())
         {
             // First check is to detect if the last created decompose is 
capable
             // to represent the now requested visualization (see similar
@@ -295,7 +295,7 @@ void SoftEdgePrimitive2D::get2DDecomposition(
             }
         }
 
-        if (!getBuffered2DDecomposition().empty())
+        if (hasBuffered2DDecomposition())
         {
             // Second check is to react on changes of the DiscreteSoftRadius 
when
             // zooming in/out (see similar implementation at GlowPrimitive2D).
@@ -321,7 +321,7 @@ void SoftEdgePrimitive2D::get2DDecomposition(
             }
         }
 
-        if (getBuffered2DDecomposition().empty())
+        if (!hasBuffered2DDecomposition())
         {
             // refresh last used DiscreteSoftRadius and ClippedRange to new 
remembered values
             const_cast<SoftEdgePrimitive2D*>(this)->mfLastDiscreteSoftRadius = 
fDiscreteSoftRadius;
diff --git 
a/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx 
b/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
index f160a1ec118b..9ea787bb9d38 100644
--- a/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
+++ b/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
@@ -50,7 +50,7 @@ private:
 
 protected:
     /// identical to BufferedDecompositionPrimitive2D, see there please
-    const Primitive2DContainer& getBuffered2DDecomposition() const;
+    bool hasBuffered2DDecomposition() const;
     void setBuffered2DDecomposition(Primitive2DContainer&& rNew);
 
     /// method which is to be used to implement the local decomposition of a 
2D group primitive.

Reply via email to