Title: [294985] trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js
Revision
294985
Author
drou...@apple.com
Date
2022-05-27 21:30:41 -0700 (Fri, 27 May 2022)

Log Message

Web Inspector: CSS property name counts should be updated atomically
https://bugs.webkit.org/show_bug.cgi?id=240994

Reviewed by Patrick Angle.

Consider the following example:
```
display: foo;
display: bar;
```

Before this change, the following would happen:
a. get the cached count of `display: foo`
b. increment the cached count of `display: foo` by 1
c. get the stored count of `display: foo`
d. get the cached count of `display: bar`
e. increment the cached count of `display: bar` by 1
f. get the stored count of `display: bar`
(async)
g. increment the stored count of `display: foo` (from c) by 1
(async)
h. increment the stored count of `display: bar` (from f) by 1

The problem is that g/h get the same stored count because c/f happened before any updates occurred.

After this change, the following would happen:
a. get the cached count of `display: foo`
b. increment the cached count of `display: foo` by 1
c. get the cached count of `display: bar`
d. increment the cached count of `display: bar` by 1
(async)
e. get the stored count of `display: foo`
(async)
f. increment the stored count of `display: foo` (from e) by 1
(async)
g. get the stored count of `display: bar`
(async)
h. increment the stored count of `display: bar` (from g) by 1

By ensuring there is never more than one active operation on `WI.objectStores.cssPropertyNameCounts`
at a time, it is guaranteed that values will never be trampled over (though it takes a bit longer).

* Source/WebInspectorUI/UserInterface/Models/CSSProperty.js:
(WI.CSSProperty._initializePropertyNameCounts):
(WI.CSSProperty.prototype._updateName.changeCount):

Canonical link: https://commits.webkit.org/251089@main

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js (294984 => 294985)


--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js	2022-05-28 04:22:16 UTC (rev 294984)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js	2022-05-28 04:30:41 UTC (rev 294985)
@@ -119,12 +119,15 @@
 
         WI.CSSProperty._cachedNameCounts = {};
 
-        WI.objectStores.cssPropertyNameCounts.getAllKeys().then((propertyNames) => {
-            for (let propertyName of propertyNames) {
-                WI.objectStores.cssPropertyNameCounts.get(propertyName).then((storedCount) => {
+        WI.CSSProperty._storedNameCountsQueue = new Promise((resolve, reject) => {
+            WI.objectStores.cssPropertyNameCounts.getAllKeys().then((propertyNames) => {
+                Promise.allSettled(propertyNames.map(async (propertyName) => {
+                    let storedCount = await WI.objectStores.cssPropertyNameCounts.get(propertyName);
+
                     WI.CSSProperty._cachedNameCounts[propertyName] = (WI.CSSProperty._cachedNameCounts[propertyName] || 0) + storedCount;
-                });
-            }
+                }))
+                .then(resolve, reject);
+            });
         });
     }
 
@@ -567,9 +570,11 @@
             console.assert(delta > 0 || cachedCount >= delta, cachedCount, delta);
             WI.CSSProperty._cachedNameCounts[propertyName] = Math.max(0, (cachedCount || 0) + delta);
 
-            WI.objectStores.cssPropertyNameCounts.get(propertyName).then((storedCount) => {
+            WI.CSSProperty._storedNameCountsQueue = WI.CSSProperty._storedNameCountsQueue.finally(async () => {
+                let storedCount = await WI.objectStores.cssPropertyNameCounts.get(propertyName);
+
                 console.assert(delta > 0 || storedCount >= delta, storedCount, delta);
-                WI.objectStores.cssPropertyNameCounts.put(Math.max(0, (storedCount || 0) + delta), propertyName);
+                await WI.objectStores.cssPropertyNameCounts.put(Math.max(0, (storedCount || 0) + delta), propertyName);
             });
 
             if (propertyName !== this.canonicalName)
@@ -616,6 +621,7 @@
 };
 
 WI.CSSProperty._cachedNameCounts = null;
+WI.CSSProperty._storedNameCountsQueue = null;
 
 WI.CSSProperty.Event = {
     Changed: "css-property-changed",
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to