Add flush mechanism to buffered Primitives II

As sberg mentioned in previous change this might be responsible
for heap-use-after-free problems. I took a look and it seems
to be possible that the timer calls back while deletion of the
helper is in progress, so I try now to first stop the timer
and then delete so that it cannot trigger. Will see if that
works - if not I might have to use another lock...

Change-Id: I1ae27d9ed890f352904cab18c3292b449659a3ce
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161128
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
diff --git a/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx b/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx
index 4b5f52b..537a0106 100644
--- a/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D.cxx
@@ -66,17 +66,21 @@ void BufferedDecompositionGroupPrimitive2D::setBuffered2DDecomposition(Primitive
{
    if (0 != maCallbackSeconds)
    {
        if (rNew.empty())
        if (maCallbackTimer.is())
        {
            // no more decomposition, end callback
            maCallbackTimer.clear();
            if (rNew.empty())
            {
                // no more decomposition, end callback
                maCallbackTimer->stop();
                maCallbackTimer.clear();
            }
            else
            {
                // decomposition changed, touch
                maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
            }
        }
        else if (maCallbackTimer.is())
        {
            // decomposition changed, touch
            maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
        }
        else
        else if (!rNew.empty())
        {
            // decomposition changed, start callback
            maCallbackTimer.set(new LocalCallbackTimer(*this));
@@ -96,6 +100,16 @@ BufferedDecompositionGroupPrimitive2D::BufferedDecompositionGroupPrimitive2D(
{
}

BufferedDecompositionGroupPrimitive2D::~BufferedDecompositionGroupPrimitive2D()
{
    if (maCallbackTimer.is())
    {
        // no more decomposition, end callback
        maCallbackTimer->stop();
        maCallbackTimer.clear();
    }
}

void BufferedDecompositionGroupPrimitive2D::get2DDecomposition(
    Primitive2DDecompositionVisitor& rVisitor,
    const geometry::ViewInformation2D& rViewInformation) const
diff --git a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
index 53b6f87..0ed2212 100644
--- a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
@@ -65,17 +65,21 @@ void BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DCon
{
    if (0 != maCallbackSeconds)
    {
        if (rNew.empty())
        if (maCallbackTimer.is())
        {
            // no more decomposition, end callback
            maCallbackTimer.clear();
            if (rNew.empty())
            {
                // no more decomposition, end callback
                maCallbackTimer->stop();
                maCallbackTimer.clear();
            }
            else
            {
                // decomposition changed, touch
                maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
            }
        }
        else if (maCallbackTimer.is())
        {
            // decomposition changed, touch
            maCallbackTimer->setRemainingTime(salhelper::TTimeValue(maCallbackSeconds, 0));
        }
        else
        else if (!rNew.empty())
        {
            // decomposition changed, start callback
            maCallbackTimer.set(new LocalCallbackTimer(*this));
@@ -95,7 +99,15 @@ BufferedDecompositionPrimitive2D::BufferedDecompositionPrimitive2D()
{
}

BufferedDecompositionPrimitive2D::~BufferedDecompositionPrimitive2D() {}
BufferedDecompositionPrimitive2D::~BufferedDecompositionPrimitive2D()
{
    if (maCallbackTimer.is())
    {
        // no more decomposition, end callback
        maCallbackTimer->stop();
        maCallbackTimer.clear();
    }
}

void BufferedDecompositionPrimitive2D::get2DDecomposition(
    Primitive2DDecompositionVisitor& rVisitor,
diff --git a/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx b/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
index c3bc54e..031bd36 100644
--- a/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
+++ b/include/drawinglayer/primitive2d/BufferedDecompositionGroupPrimitive2D.hxx
@@ -65,6 +65,7 @@ protected:
public:
    /// constructor/destructor. For GroupPrimitive2D we need the child parameter, too.
    BufferedDecompositionGroupPrimitive2D(Primitive2DContainer&& aChildren);
    virtual ~BufferedDecompositionGroupPrimitive2D();

    /// identical to BufferedDecompositionPrimitive2D, see there please
    virtual void