Title: [276283] trunk/Source/WebCore
Revision
276283
Author
[email protected]
Date
2021-04-19 21:45:42 -0700 (Mon, 19 Apr 2021)

Log Message

cachedCGColor() and nsColor() are not thread-safe
https://bugs.webkit.org/show_bug.cgi?id=223033

Reviewed by Chris Dumez.

These functions will break if they are used by a worker thread.

* platform/graphics/cg/ColorCG.cpp:
(WebCore::cachedCGColor):
* platform/graphics/mac/ColorMac.mm:
(WebCore::nsColor):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (276282 => 276283)


--- trunk/Source/WebCore/ChangeLog	2021-04-20 03:26:59 UTC (rev 276282)
+++ trunk/Source/WebCore/ChangeLog	2021-04-20 04:45:42 UTC (rev 276283)
@@ -1,3 +1,17 @@
+2021-04-19  Said Abou-Hallawa  <[email protected]>
+
+        cachedCGColor() and nsColor() are not thread-safe
+        https://bugs.webkit.org/show_bug.cgi?id=223033
+
+        Reviewed by Chris Dumez.
+
+        These functions will break if they are used by a worker thread.
+
+        * platform/graphics/cg/ColorCG.cpp:
+        (WebCore::cachedCGColor):
+        * platform/graphics/mac/ColorMac.mm:
+        (WebCore::nsColor):
+
 2021-04-19  Wenson Hsieh  <[email protected]>
 
         Rename FloatQuad::isEmpty() to boundingBoxIsEmpty() and reimplement isEmpty()

Modified: trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp (276282 => 276283)


--- trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp	2021-04-20 03:26:59 UTC (rev 276282)
+++ trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp	2021-04-20 04:45:42 UTC (rev 276283)
@@ -29,7 +29,9 @@
 #if USE(CG)
 
 #include "ColorSpaceCG.h"
+#include <mutex>
 #include <wtf/Assertions.h>
+#include <wtf/Lock.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/TinyLRUCache.h>
 #include <pal/spi/cg/CoreGraphicsSPI.h>
@@ -126,20 +128,35 @@
     if (auto srgb = color.tryGetAsSRGBABytes()) {
         switch (PackedColor::RGBA { *srgb }.value) {
         case PackedColor::RGBA { Color::transparentBlack }.value: {
-            static NeverDestroyed<RetainPtr<CGColorRef>> transparentCGColor = createCGColor(color);
+            static LazyNeverDestroyed<RetainPtr<CGColorRef>> transparentCGColor;
+            static std::once_flag onceFlag;
+            std::call_once(onceFlag, [] {
+                transparentCGColor.construct(createCGColor(Color::transparentBlack));
+            });
             return transparentCGColor.get().get();
         }
         case PackedColor::RGBA { Color::black }.value: {
-            static NeverDestroyed<RetainPtr<CGColorRef>> blackCGColor = createCGColor(color);
+            static LazyNeverDestroyed<RetainPtr<CGColorRef>> blackCGColor;
+            static std::once_flag onceFlag;
+            std::call_once(onceFlag, [] {
+                blackCGColor.construct(createCGColor(Color::black));
+            });
             return blackCGColor.get().get();
         }
         case PackedColor::RGBA { Color::white }.value: {
-            static NeverDestroyed<RetainPtr<CGColorRef>> whiteCGColor = createCGColor(color);
+            static LazyNeverDestroyed<RetainPtr<CGColorRef>> whiteCGColor;
+            static std::once_flag onceFlag;
+            std::call_once(onceFlag, [] {
+                whiteCGColor.construct(createCGColor(Color::white));
+            });
             return whiteCGColor.get().get();
         }
         }
     }
 
+    static Lock cachedColorLock;
+    auto holder = holdLock(cachedColorLock);
+
     static NeverDestroyed<TinyLRUCache<Color, RetainPtr<CGColorRef>, 32>> cache;
     return cache.get().get(color).get();
 }

Modified: trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm (276282 => 276283)


--- trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm	2021-04-20 03:26:59 UTC (rev 276282)
+++ trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm	2021-04-20 04:45:42 UTC (rev 276283)
@@ -30,6 +30,7 @@
 
 #import "LocalCurrentGraphicsContext.h"
 #import <wtf/BlockObjCExceptions.h>
+#import <wtf/Lock.h>
 #import <wtf/NeverDestroyed.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/TinyLRUCache.h>
@@ -116,20 +117,35 @@
     if (auto srgb = color.tryGetAsSRGBABytes()) {
         switch (PackedColor::RGBA { *srgb }.value) {
         case PackedColor::RGBA { Color::transparentBlack }.value: {
-            static NeverDestroyed<RetainPtr<NSColor>> clearColor = [NSColor colorWithSRGBRed:0 green:0 blue:0 alpha:0];
+            static LazyNeverDestroyed<RetainPtr<NSColor>> clearColor;
+            static std::once_flag onceFlag;
+            std::call_once(onceFlag, [] {
+                clearColor.construct([NSColor colorWithSRGBRed:0 green:0 blue:0 alpha:0]);
+            });
             return clearColor.get().get();
         }
         case PackedColor::RGBA { Color::black }.value: {
-            static NeverDestroyed<RetainPtr<NSColor>> blackColor = [NSColor colorWithSRGBRed:0 green:0 blue:0 alpha:1];
+            static LazyNeverDestroyed<RetainPtr<NSColor>> blackColor;
+            static std::once_flag onceFlag;
+            std::call_once(onceFlag, [] {
+                blackColor.construct([NSColor colorWithSRGBRed:0 green:0 blue:0 alpha:1]);
+            });
             return blackColor.get().get();
         }
         case PackedColor::RGBA { Color::white }.value: {
-            static NeverDestroyed<RetainPtr<NSColor>> whiteColor = [NSColor colorWithSRGBRed:1 green:1 blue:1 alpha:1];
+            static LazyNeverDestroyed<RetainPtr<NSColor>> whiteColor;
+            static std::once_flag onceFlag;
+            std::call_once(onceFlag, [] {
+                whiteColor.construct([NSColor colorWithSRGBRed:1 green:1 blue:1 alpha:1]);
+            });
             return whiteColor.get().get();
         }
         }
     }
 
+    static Lock cachedColorLock;
+    auto holder = holdLock(cachedColorLock);
+
     static NeverDestroyed<TinyLRUCache<Color, RetainPtr<NSColor>, 32>> cache;
     return cache.get().get(color).get();
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to