From 3c9d8d6460e77526ece3da7a46578f7471554877 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sun, 15 Nov 2015 22:03:14 +0100 Subject: [PATCH] app_server: fix race condition in alpha mask cloning * Add a lock which is acquired when reattaching/regenerating masks, and also acquired for a cached mask before making a clone of it, to prevent the clone from having an inconsistent state in concurrent edge cases. * Maybe fixes #12469 --- src/servers/app/drawing/AlphaMask.cpp | 7 +++++++ src/servers/app/drawing/AlphaMask.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 3716c7be8ab..9ed68dc6e06 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -22,6 +22,8 @@ #include "Shape.h" #include "ShapePrivate.h" +#include + // #pragma mark - AlphaMask @@ -103,6 +105,8 @@ AlphaMask::~AlphaMask() IntPoint AlphaMask::SetCanvasGeometry(IntPoint origin, IntRect bounds) { + AutoLocker locker(fLock); + if (origin == fCanvasOrigin && bounds.Width() == fCanvasBounds.Width() && bounds.Height() == fCanvasBounds.Height()) return fCanvasOrigin; @@ -159,6 +163,8 @@ AlphaMask::_CreateTemporaryBitmap(BRect bounds) const void AlphaMask::_Generate() { + AutoLocker locker(fLock); + ServerBitmap* const bitmap = _RenderSource(fCanvasBounds); BReference bitmapRef(bitmap, true); if (bitmap == NULL) { @@ -484,6 +490,7 @@ ShapeAlphaMask::Create(AlphaMask* previousMask, const shape_data& shape, // TODO: don't make a new mask if the cache entry has no drawstate // using it anymore, because then we ca just immediately reuse it AlphaMask* cachedMask = mask; + AutoLocker locker(mask->fLock); mask = new(std::nothrow) ShapeAlphaMask(previousMask, mask); cachedMask->ReleaseReference(); } diff --git a/src/servers/app/drawing/AlphaMask.h b/src/servers/app/drawing/AlphaMask.h index 7d53d67c536..9156c235824 100644 --- a/src/servers/app/drawing/AlphaMask.h +++ b/src/servers/app/drawing/AlphaMask.h @@ -15,6 +15,8 @@ #include "drawing/Painter/defines.h" #include "IntRect.h" +#include + class BShape; class ServerBitmap; @@ -63,6 +65,7 @@ class AlphaMask : public BReferenceable { BReference fPreviousMask; IntRect fBounds; bool fClippedToCanvas; + BLocker fLock; private: friend class AlphaMaskCache;