Keep track of pending value changes in StorageAreaProxy
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Mar 2013 00:59:59 +0000 (00:59 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Mar 2013 00:59:59 +0000 (00:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=111496

Reviewed by Beth Dakin.

Add a HashCountedSet to keep track of the number of pending value
changes for a given key. If we get incoming storage events from other
processes while we have pending value changes, ignore the events.

* WebProcess/Storage/StorageAreaProxy.cpp:
(WebKit::StorageAreaProxy::setItem):
(WebKit::StorageAreaProxy::didSetItem):
(WebKit::StorageAreaProxy::dispatchStorageEvent):
(WebKit::StorageAreaProxy::shouldApplyChangesForKey):
(WebKit):
* WebProcess/Storage/StorageAreaProxy.h:
(StorageAreaProxy):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@144850 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Storage/StorageAreaProxy.cpp
Source/WebKit2/WebProcess/Storage/StorageAreaProxy.h

index 9759d74..3a0ac81 100644 (file)
@@ -1,3 +1,23 @@
+2013-03-05  Anders Carlsson  <andersca@apple.com>
+
+        Keep track of pending value changes in StorageAreaProxy
+        https://bugs.webkit.org/show_bug.cgi?id=111496
+
+        Reviewed by Beth Dakin.
+
+        Add a HashCountedSet to keep track of the number of pending value
+        changes for a given key. If we get incoming storage events from other
+        processes while we have pending value changes, ignore the events.
+
+        * WebProcess/Storage/StorageAreaProxy.cpp:
+        (WebKit::StorageAreaProxy::setItem):
+        (WebKit::StorageAreaProxy::didSetItem):
+        (WebKit::StorageAreaProxy::dispatchStorageEvent):
+        (WebKit::StorageAreaProxy::shouldApplyChangesForKey):
+        (WebKit):
+        * WebProcess/Storage/StorageAreaProxy.h:
+        (StorageAreaProxy):
+
 2013-03-05  Ryuan Choi  <ryuan.choi@samsung.com>
 
         [EFL] Build break with latest EFL libraries
index f625979..a777e13 100644 (file)
@@ -142,6 +142,8 @@ void StorageAreaProxy::setItem(const String& key, const String& value, Exception
     if (oldValue == value)
         return;
 
+    m_pendingValueChanges.add(key);
+
     WebProcess::shared().connection()->send(Messages::StorageManager::SetItem(m_storageAreaID, key, value, sourceFrame->document()->url()), 0);
 }
 
@@ -201,11 +203,18 @@ void StorageAreaProxy::closeDatabaseIfIdle()
 
 void StorageAreaProxy::didSetItem(const String& key, bool quotaError)
 {
+    ASSERT(m_pendingValueChanges.contains(key));
+
+    m_pendingValueChanges.remove(key);
+
     // FIXME: Implement this.
 }
 
 void StorageAreaProxy::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, const String& urlString)
 {
+    if (!shouldApplyChangesForKey(key))
+        return;
+
     // FIXME: Implement this.
 }
 
@@ -229,6 +238,21 @@ bool StorageAreaProxy::disabledByPrivateBrowsingInFrame(const Frame* sourceFrame
     return !SchemeRegistry::allowsLocalStorageAccessInPrivateBrowsing(sourceFrame->document()->securityOrigin()->protocol());
 }
 
+bool StorageAreaProxy::shouldApplyChangesForKey(const String& key) const
+{
+    // We have not yet loaded anything from this storage map.
+    if (!m_storageMap)
+        return false;
+
+    // Check if this storage area is currently waiting for the storage manager to update the given key.
+    // If that is the case, we don't want to apply any changes made by other storage areas, since
+    // our change was made last.
+    if (m_pendingValueChanges.contains(key))
+        return false;
+
+    return true;
+}
+
 void StorageAreaProxy::loadValuesIfNeeded()
 {
     if (m_storageMap)
index f83b4ac..39194c8 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "MessageReceiver.h"
 #include <WebCore/StorageArea.h>
+#include <wtf/HashCountedSet.h>
 #include <wtf/HashMap.h>
 
 namespace WebCore {
@@ -69,12 +70,15 @@ private:
     WebCore::StorageType storageType() const;
     bool disabledByPrivateBrowsingInFrame(const WebCore::Frame* sourceFrame) const;
 
+    bool shouldApplyChangesForKey(const String& key) const;
     void loadValuesIfNeeded();
 
     uint64_t m_storageNamespaceID;
     unsigned m_quotaInBytes;
     uint64_t m_storageAreaID;
     RefPtr<WebCore::StorageMap> m_storageMap;
+
+    HashCountedSet<String> m_pendingValueChanges;
 };
 
 } // namespace WebKit