From f0a8640b45451b9891fa641144acc33b90ac9a23 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 22 May 2020 21:50:46 -0400 Subject: [PATCH] app_server: Add locking to the Decorator class. This class can potentially be accessed by multiple "tabs" (windows) at once, so it must be read/write locked to account for that. Fixes #16027. Change-Id: I9cc741874caed4997497b03c8893bc2acb0e6fe7 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2779 Reviewed-by: waddlesplash --- src/servers/app/decorator/Decorator.cpp | 78 +++++++++++++++++++++++++ src/servers/app/decorator/Decorator.h | 4 ++ 2 files changed, 82 insertions(+) diff --git a/src/servers/app/decorator/Decorator.cpp b/src/servers/app/decorator/Decorator.cpp index d35c49edf9..0a2d3dd494 100644 --- a/src/servers/app/decorator/Decorator.cpp +++ b/src/servers/app/decorator/Decorator.cpp @@ -74,6 +74,8 @@ Decorator::Tab::Tab() Decorator::Decorator(DesktopSettings& settings, BRect frame, Desktop* desktop) : + fLocker("Decorator"), + fDrawingEngine(NULL), fDrawState(), @@ -111,6 +113,8 @@ Decorator::Tab* Decorator::AddTab(DesktopSettings& settings, const char* title, window_look look, uint32 flags, int32 index, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + Decorator::Tab* tab = _AllocateNewTab(); if (tab == NULL) return NULL; @@ -147,6 +151,8 @@ Decorator::AddTab(DesktopSettings& settings, const char* title, bool Decorator::RemoveTab(int32 index, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + Decorator::Tab* tab = fTabList.RemoveItemAt(index); if (tab == NULL) return false; @@ -162,6 +168,8 @@ Decorator::RemoveTab(int32 index, BRegion* updateRegion) bool Decorator::MoveTab(int32 from, int32 to, bool isMoving, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + if (_MoveTab(from, to, isMoving, updateRegion) == false) return false; if (fTabList.MoveItem(from, to) == false) { @@ -176,6 +184,8 @@ Decorator::MoveTab(int32 from, int32 to, bool isMoving, BRegion* updateRegion) int32 Decorator::TabAt(const BPoint& where) const { + AutoReadLocker _(fLocker); + for (int32 i = 0; i < fTabList.CountItems(); i++) { Decorator::Tab* tab = fTabList.ItemAt(i); if (tab->tabRect.Contains(where)) @@ -189,6 +199,7 @@ Decorator::TabAt(const BPoint& where) const void Decorator::SetTopTab(int32 tab) { + AutoWriteLocker _(fLocker); fTopTab = fTabList.ItemAt(tab); } @@ -199,6 +210,8 @@ Decorator::SetTopTab(int32 tab) void Decorator::SetDrawingEngine(DrawingEngine* engine) { + AutoWriteLocker _(fLocker); + fDrawingEngine = engine; // lots of subclasses will depend on the driver for text support, so call // _DoLayout() after we have it @@ -217,6 +230,8 @@ Decorator::SetDrawingEngine(DrawingEngine* engine) void Decorator::SetFlags(int32 tab, uint32 flags, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + // we're nice to our subclasses - we make sure B_NOT_{H|V|}_RESIZABLE // are in sync (it's only a semantical simplification, not a necessity) if ((flags & (B_NOT_H_RESIZABLE | B_NOT_V_RESIZABLE)) @@ -239,6 +254,7 @@ Decorator::SetFlags(int32 tab, uint32 flags, BRegion* updateRegion) void Decorator::FontsChanged(DesktopSettings& settings, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); _FontsChanged(settings, updateRegion); _InvalidateFootprint(); @@ -250,6 +266,8 @@ Decorator::FontsChanged(DesktopSettings& settings, BRegion* updateRegion) void Decorator::ColorsChanged(DesktopSettings& settings, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + UpdateColors(settings); if (updateRegion != NULL) @@ -266,6 +284,8 @@ void Decorator::SetLook(int32 tab, DesktopSettings& settings, window_look look, BRegion* updateRect) { + AutoWriteLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -282,6 +302,7 @@ Decorator::SetLook(int32 tab, DesktopSettings& settings, window_look look, window_look Decorator::Look(int32 tab) const { + AutoReadLocker _(fLocker); return TabAt(tab)->look; } @@ -292,6 +313,7 @@ Decorator::Look(int32 tab) const uint32 Decorator::Flags(int32 tab) const { + AutoReadLocker _(fLocker); return TabAt(tab)->flags; } @@ -302,6 +324,7 @@ Decorator::Flags(int32 tab) const BRect Decorator::BorderRect() const { + AutoReadLocker _(fLocker); return fBorderRect; } @@ -309,6 +332,7 @@ Decorator::BorderRect() const BRect Decorator::TitleBarRect() const { + AutoReadLocker _(fLocker); return fTitleBarRect; } @@ -319,6 +343,8 @@ Decorator::TitleBarRect() const BRect Decorator::TabRect(int32 tab) const { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return BRect(); @@ -344,6 +370,8 @@ Decorator::TabRect(Decorator::Tab* tab) const void Decorator::SetClose(int32 tab, bool pressed) { + AutoWriteLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -365,6 +393,8 @@ Decorator::SetClose(int32 tab, bool pressed) void Decorator::SetMinimize(int32 tab, bool pressed) { + AutoWriteLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -385,6 +415,8 @@ Decorator::SetMinimize(int32 tab, bool pressed) void Decorator::SetZoom(int32 tab, bool pressed) { + AutoWriteLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -402,6 +434,8 @@ Decorator::SetZoom(int32 tab, bool pressed) void Decorator::SetTitle(int32 tab, const char* string, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -422,6 +456,8 @@ Decorator::SetTitle(int32 tab, const char* string, BRegion* updateRegion) const char* Decorator::Title(int32 tab) const { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return ""; @@ -433,6 +469,7 @@ Decorator::Title(int32 tab) const const char* Decorator::Title(Decorator::Tab* tab) const { + AutoReadLocker _(fLocker); return tab->title; } @@ -440,6 +477,8 @@ Decorator::Title(Decorator::Tab* tab) const float Decorator::TabLocation(int32 tab) const { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = _TabAt(tab); if (decoratorTab == NULL) return 0.0f; @@ -452,6 +491,8 @@ bool Decorator::SetTabLocation(int32 tab, float location, bool isShifting, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return false; @@ -474,6 +515,8 @@ Decorator::SetTabLocation(int32 tab, float location, bool isShifting, void Decorator::SetFocus(int32 tab, bool active) { + AutoWriteLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -486,6 +529,8 @@ Decorator::SetFocus(int32 tab, bool active) bool Decorator::IsFocus(int32 tab) const { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return false; @@ -497,6 +542,7 @@ Decorator::IsFocus(int32 tab) const bool Decorator::IsFocus(Decorator::Tab* tab) const { + AutoReadLocker _(fLocker); return tab->isFocused; } @@ -509,6 +555,8 @@ Decorator::IsFocus(Decorator::Tab* tab) const const BRegion& Decorator::GetFootprint() { + AutoReadLocker _(fLocker); + if (!fFootprintValid) { _GetFootprint(&fFootprint); fFootprintValid = true; @@ -522,6 +570,7 @@ Decorator::GetFootprint() ::Desktop* Decorator::GetDesktop() { + AutoReadLocker _(fLocker); return fDesktop; } @@ -551,6 +600,8 @@ Decorator::GetDesktop() Decorator::Region Decorator::RegionAt(BPoint where, int32& tabIndex) const { + AutoReadLocker _(fLocker); + tabIndex = -1; for (int32 i = 0; i < fTabList.CountItems(); i++) { @@ -600,6 +651,8 @@ Decorator::MoveBy(float x, float y) void Decorator::MoveBy(BPoint offset) { + AutoWriteLocker _(fLocker); + if (fFootprintValid) fFootprint.OffsetBy(offset.x, offset.y); @@ -627,6 +680,7 @@ Decorator::ResizeBy(float x, float y, BRegion* dirty) void Decorator::ResizeBy(BPoint offset, BRegion* dirty) { + AutoWriteLocker _(fLocker); _ResizeBy(offset, dirty); _InvalidateFootprint(); } @@ -635,6 +689,8 @@ Decorator::ResizeBy(BPoint offset, BRegion* dirty) void Decorator::ExtendDirtyRegion(Region region, BRegion& dirty) { + AutoReadLocker _(fLocker); + switch (region) { case REGION_TAB: dirty.Include(fTitleBarRect); @@ -717,6 +773,8 @@ bool Decorator::SetRegionHighlight(Region region, uint8 highlight, BRegion* dirty, int32 tab) { + AutoWriteLocker _(fLocker); + int32 index = (int32)region - 1; if (index < 0 || index >= REGION_COUNT - 1) return false; @@ -735,6 +793,8 @@ Decorator::SetRegionHighlight(Region region, uint8 highlight, BRegion* dirty, bool Decorator::SetSettings(const BMessage& settings, BRegion* updateRegion) { + AutoWriteLocker _(fLocker); + if (_SetSettings(settings, updateRegion)) { _InvalidateFootprint(); return true; @@ -746,6 +806,8 @@ Decorator::SetSettings(const BMessage& settings, BRegion* updateRegion) bool Decorator::GetSettings(BMessage* settings) const { + AutoReadLocker _(fLocker); + if (!fTitleBarRect.IsValid()) return false; @@ -771,6 +833,8 @@ void Decorator::GetSizeLimits(int32* minWidth, int32* minHeight, int32* maxWidth, int32* maxHeight) const { + AutoReadLocker _(fLocker); + float minTabSize = 0; if (CountTabs() > 0) minTabSize = _TabAt(0)->minTabSize; @@ -790,6 +854,8 @@ Decorator::GetSizeLimits(int32* minWidth, int32* minHeight, void Decorator::DrawTab(int32 tabIndex) { + AutoReadLocker _(fLocker); + Decorator::Tab* tab = fTabList.ItemAt(tabIndex); if (tab == NULL) return; @@ -806,6 +872,8 @@ Decorator::DrawTab(int32 tabIndex) void Decorator::DrawTitle(int32 tab) { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -817,6 +885,8 @@ Decorator::DrawTitle(int32 tab) void Decorator::DrawClose(int32 tab) { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -829,6 +899,8 @@ Decorator::DrawClose(int32 tab) void Decorator::DrawMinimize(int32 tab) { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -841,6 +913,8 @@ Decorator::DrawMinimize(int32 tab) void Decorator::DrawZoom(int32 tab) { + AutoReadLocker _(fLocker); + Decorator::Tab* decoratorTab = fTabList.ItemAt(tab); if (decoratorTab == NULL) return; @@ -851,6 +925,7 @@ Decorator::DrawZoom(int32 tab) rgb_color Decorator::UIColor(color_which which) { + AutoReadLocker _(fLocker); DesktopSettings settings(fDesktop); return settings.UIColor(which); } @@ -859,6 +934,7 @@ Decorator::UIColor(color_which which) float Decorator::BorderWidth() { + AutoReadLocker _(fLocker); return fBorderWidth; } @@ -866,6 +942,8 @@ Decorator::BorderWidth() float Decorator::TabHeight() { + AutoReadLocker _(fLocker); + if (fTitleBarRect.IsValid()) return fTitleBarRect.Height(); diff --git a/src/servers/app/decorator/Decorator.h b/src/servers/app/decorator/Decorator.h index 44440a83ca..346dbb60b1 100644 --- a/src/servers/app/decorator/Decorator.h +++ b/src/servers/app/decorator/Decorator.h @@ -20,6 +20,7 @@ #include #include "DrawState.h" +#include "MultiLocker.h" class Desktop; class DesktopSettings; @@ -269,6 +270,9 @@ protected: void _InvalidateBitmaps(); +protected: + mutable MultiLocker fLocker; + DrawingEngine* fDrawingEngine; DrawState fDrawState;