summaryrefslogtreecommitdiff
path: root/Source/WebCore/storage
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/storage')
-rw-r--r--Source/WebCore/storage/Storage.cpp111
-rw-r--r--Source/WebCore/storage/Storage.h29
-rw-r--r--Source/WebCore/storage/Storage.idl12
-rw-r--r--Source/WebCore/storage/StorageArea.h15
-rw-r--r--Source/WebCore/storage/StorageAreaImpl.cpp306
-rw-r--r--Source/WebCore/storage/StorageAreaImpl.h100
-rw-r--r--Source/WebCore/storage/StorageAreaSync.cpp531
-rw-r--r--Source/WebCore/storage/StorageAreaSync.h108
-rw-r--r--Source/WebCore/storage/StorageEvent.cpp21
-rw-r--r--Source/WebCore/storage/StorageEvent.h34
-rw-r--r--Source/WebCore/storage/StorageEvent.idl38
-rw-r--r--Source/WebCore/storage/StorageEventDispatcher.cpp46
-rw-r--r--Source/WebCore/storage/StorageEventDispatcher.h17
-rw-r--r--Source/WebCore/storage/StorageMap.cpp38
-rw-r--r--Source/WebCore/storage/StorageMap.h29
-rw-r--r--Source/WebCore/storage/StorageNamespace.h22
-rw-r--r--Source/WebCore/storage/StorageNamespaceImpl.cpp195
-rw-r--r--Source/WebCore/storage/StorageNamespaceImpl.h80
-rw-r--r--Source/WebCore/storage/StorageNamespaceProvider.cpp101
-rw-r--r--Source/WebCore/storage/StorageNamespaceProvider.h (renamed from Source/WebCore/storage/StorageStrategy.h)45
-rw-r--r--Source/WebCore/storage/StorageStrategy.cpp48
-rw-r--r--Source/WebCore/storage/StorageSyncManager.cpp93
-rw-r--r--Source/WebCore/storage/StorageSyncManager.h63
-rw-r--r--Source/WebCore/storage/StorageThread.cpp115
-rw-r--r--Source/WebCore/storage/StorageThread.h67
-rw-r--r--Source/WebCore/storage/StorageTracker.cpp626
-rw-r--r--Source/WebCore/storage/StorageTracker.h120
-rw-r--r--Source/WebCore/storage/StorageTrackerClient.h42
-rw-r--r--Source/WebCore/storage/StorageType.h (renamed from Source/WebCore/storage/StorageNamespace.cpp)26
29 files changed, 312 insertions, 2766 deletions
diff --git a/Source/WebCore/storage/Storage.cpp b/Source/WebCore/storage/Storage.cpp
index c484b96aa..11f919a82 100644
--- a/Source/WebCore/storage/Storage.cpp
+++ b/Source/WebCore/storage/Storage.cpp
@@ -31,21 +31,21 @@
#include "Frame.h"
#include "Page.h"
#include "SchemeRegistry.h"
-#include "Settings.h"
+#include "SecurityOrigin.h"
#include "StorageArea.h"
-#include <wtf/PassRefPtr.h>
+#include "StorageType.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
-PassRefPtr<Storage> Storage::create(Frame* frame, PassRefPtr<StorageArea> storageArea)
+Ref<Storage> Storage::create(Frame* frame, RefPtr<StorageArea>&& storageArea)
{
- return adoptRef(new Storage(frame, storageArea));
+ return adoptRef(*new Storage(frame, WTFMove(storageArea)));
}
-Storage::Storage(Frame* frame, PassRefPtr<StorageArea> storageArea)
+Storage::Storage(Frame* frame, RefPtr<StorageArea>&& storageArea)
: DOMWindowProperty(frame)
- , m_storageArea(storageArea)
+ , m_storageArea(WTFMove(storageArea))
{
ASSERT(m_frame);
ASSERT(m_storageArea);
@@ -58,115 +58,66 @@ Storage::~Storage()
m_storageArea->decrementAccessCount();
}
-unsigned Storage::length(ExceptionCode& ec) const
+ExceptionOr<unsigned> Storage::length() const
{
- ec = 0;
- if (!m_storageArea->canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return 0;
- }
-
- if (isDisabledByPrivateBrowsing())
- return 0;
+ if (!m_storageArea->canAccessStorage(m_frame))
+ return Exception { SECURITY_ERR };
return m_storageArea->length();
}
-String Storage::key(unsigned index, ExceptionCode& ec) const
+ExceptionOr<String> Storage::key(unsigned index) const
{
- if (!m_storageArea->canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return String();
- }
-
- if (isDisabledByPrivateBrowsing())
- return String();
+ if (!m_storageArea->canAccessStorage(m_frame))
+ return Exception { SECURITY_ERR };
return m_storageArea->key(index);
}
-String Storage::getItem(const String& key, ExceptionCode& ec) const
+ExceptionOr<String> Storage::getItem(const String& key) const
{
- if (!m_storageArea->canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return String();
- }
-
- if (isDisabledByPrivateBrowsing())
- return String();
+ if (!m_storageArea->canAccessStorage(m_frame))
+ return Exception { SECURITY_ERR };
return m_storageArea->item(key);
}
-void Storage::setItem(const String& key, const String& value, ExceptionCode& ec)
+ExceptionOr<void> Storage::setItem(const String& key, const String& value)
{
- if (!m_storageArea->canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return;
- }
-
- if (isDisabledByPrivateBrowsing()) {
- ec = QUOTA_EXCEEDED_ERR;
- return;
- }
+ if (!m_storageArea->canAccessStorage(m_frame))
+ return Exception { SECURITY_ERR };
bool quotaException = false;
m_storageArea->setItem(m_frame, key, value, quotaException);
-
if (quotaException)
- ec = QUOTA_EXCEEDED_ERR;
+ return Exception { QUOTA_EXCEEDED_ERR };
+ return { };
}
-void Storage::removeItem(const String& key, ExceptionCode& ec)
+ExceptionOr<void> Storage::removeItem(const String& key)
{
- if (!m_storageArea->canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return;
- }
-
- if (isDisabledByPrivateBrowsing())
- return;
+ if (!m_storageArea->canAccessStorage(m_frame))
+ return Exception { SECURITY_ERR };
m_storageArea->removeItem(m_frame, key);
+ return { };
}
-void Storage::clear(ExceptionCode& ec)
+ExceptionOr<void> Storage::clear()
{
- if (!m_storageArea->canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return;
- }
-
- if (isDisabledByPrivateBrowsing())
- return;
+ if (!m_storageArea->canAccessStorage(m_frame))
+ return Exception { SECURITY_ERR };
m_storageArea->clear(m_frame);
+ return { };
}
-bool Storage::contains(const String& key, ExceptionCode& ec) const
+ExceptionOr<bool> Storage::contains(const String& key) const
{
- if (!m_storageArea->canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return false;
- }
-
- if (isDisabledByPrivateBrowsing())
- return false;
+ if (!m_storageArea->canAccessStorage(m_frame))
+ return Exception { SECURITY_ERR };
return m_storageArea->contains(key);
}
-bool Storage::isDisabledByPrivateBrowsing() const
-{
- if (!m_frame->page()->settings().privateBrowsingEnabled())
- return false;
-
- if (m_storageArea->storageType() == LocalStorage) {
- if (SchemeRegistry::allowsLocalStorageAccessInPrivateBrowsing(m_frame->document()->securityOrigin()->protocol()))
- return false;
- }
-
- return true;
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/storage/Storage.h b/Source/WebCore/storage/Storage.h
index 1e9fdab76..5df3ae9a8 100644
--- a/Source/WebCore/storage/Storage.h
+++ b/Source/WebCore/storage/Storage.h
@@ -23,39 +23,34 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Storage_h
-#define Storage_h
+#pragma once
#include "DOMWindowProperty.h"
+#include "ExceptionOr.h"
#include "ScriptWrappable.h"
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
namespace WebCore {
class Frame;
class StorageArea;
-typedef int ExceptionCode;
-
class Storage : public ScriptWrappable, public RefCounted<Storage>, public DOMWindowProperty {
public:
- static PassRefPtr<Storage> create(Frame*, PassRefPtr<StorageArea>);
+ static Ref<Storage> create(Frame*, RefPtr<StorageArea>&&);
~Storage();
- unsigned length(ExceptionCode&) const;
- String key(unsigned index, ExceptionCode&) const;
- String getItem(const String& key, ExceptionCode&) const;
- void setItem(const String& key, const String& value, ExceptionCode&);
- void removeItem(const String& key, ExceptionCode&);
- void clear(ExceptionCode&);
- bool contains(const String& key, ExceptionCode&) const;
+ ExceptionOr<unsigned> length() const;
+ ExceptionOr<String> key(unsigned index) const;
+ ExceptionOr<String> getItem(const String& key) const;
+ ExceptionOr<void> setItem(const String& key, const String& value);
+ ExceptionOr<void> removeItem(const String& key);
+ ExceptionOr<void> clear();
+ ExceptionOr<bool> contains(const String& key) const;
StorageArea& area() const { return *m_storageArea; }
private:
- Storage(Frame*, PassRefPtr<StorageArea>);
+ Storage(Frame*, RefPtr<StorageArea>&&);
bool isDisabledByPrivateBrowsing() const;
@@ -63,5 +58,3 @@ private:
};
} // namespace WebCore
-
-#endif // Storage_h
diff --git a/Source/WebCore/storage/Storage.idl b/Source/WebCore/storage/Storage.idl
index 5514b9121..3d4aa56e1 100644
--- a/Source/WebCore/storage/Storage.idl
+++ b/Source/WebCore/storage/Storage.idl
@@ -30,11 +30,11 @@
CustomNamedSetter,
SkipVTableValidation,
] interface Storage {
- [NotEnumerable, GetterRaisesException] readonly attribute unsigned long length;
- [NotEnumerable, TreatReturnedNullStringAs=Null, RaisesException] DOMString key(unsigned long index);
- [NotEnumerable, TreatReturnedNullStringAs=Null, RaisesException] getter DOMString getItem(DOMString key);
- [NotEnumerable, RaisesException] void setItem(DOMString key, DOMString data);
- [NotEnumerable, RaisesException] void removeItem(DOMString key);
- [NotEnumerable, RaisesException] void clear();
+ [GetterMayThrowException] readonly attribute unsigned long length;
+ [MayThrowException] DOMString? key(unsigned long index);
+ [MayThrowException] getter DOMString? getItem(DOMString key);
+ [MayThrowException] void setItem(DOMString key, DOMString data);
+ [MayThrowException] void removeItem(DOMString key);
+ [MayThrowException] void clear();
};
diff --git a/Source/WebCore/storage/StorageArea.h b/Source/WebCore/storage/StorageArea.h
index 86e9c2051..9743fded2 100644
--- a/Source/WebCore/storage/StorageArea.h
+++ b/Source/WebCore/storage/StorageArea.h
@@ -23,20 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StorageArea_h
-#define StorageArea_h
+#pragma once
#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
class Frame;
+class SecurityOrigin;
class StorageSyncManager;
-typedef int ExceptionCode;
-enum StorageType { LocalStorage, SessionStorage };
+
+enum class StorageType;
+
+struct SecurityOriginData;
class StorageArea : public RefCounted<StorageArea> {
public:
@@ -58,8 +59,8 @@ public:
virtual void incrementAccessCount() { }
virtual void decrementAccessCount() { }
virtual void closeDatabaseIfIdle() { }
+
+ virtual SecurityOriginData securityOrigin() const = 0;
};
} // namespace WebCore
-
-#endif // StorageArea_h
diff --git a/Source/WebCore/storage/StorageAreaImpl.cpp b/Source/WebCore/storage/StorageAreaImpl.cpp
deleted file mode 100644
index 74e2c81ff..000000000
--- a/Source/WebCore/storage/StorageAreaImpl.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "StorageAreaImpl.h"
-
-#include "Document.h"
-#include "ExceptionCode.h"
-#include "Frame.h"
-#include "Page.h"
-#include "SchemeRegistry.h"
-#include "SecurityOrigin.h"
-#include "Settings.h"
-#include "StorageAreaSync.h"
-#include "StorageEventDispatcher.h"
-#include "StorageMap.h"
-#include "StorageSyncManager.h"
-#include "StorageTracker.h"
-#include <wtf/MainThread.h>
-
-namespace WebCore {
-
-StorageAreaImpl::~StorageAreaImpl()
-{
- ASSERT(isMainThread());
-}
-
-inline StorageAreaImpl::StorageAreaImpl(StorageType storageType, PassRefPtr<SecurityOrigin> origin, PassRefPtr<StorageSyncManager> syncManager, unsigned quota)
- : m_storageType(storageType)
- , m_securityOrigin(origin)
- , m_storageMap(StorageMap::create(quota))
- , m_storageSyncManager(syncManager)
-#ifndef NDEBUG
- , m_isShutdown(false)
-#endif
- , m_accessCount(0)
- , m_closeDatabaseTimer(this, &StorageAreaImpl::closeDatabaseTimerFired)
-{
- ASSERT(isMainThread());
- ASSERT(m_securityOrigin);
- ASSERT(m_storageMap);
-
- // Accessing the shared global StorageTracker when a StorageArea is created
- // ensures that the tracker is properly initialized before anyone actually needs to use it.
- StorageTracker::tracker();
-}
-
-PassRefPtr<StorageAreaImpl> StorageAreaImpl::create(StorageType storageType, PassRefPtr<SecurityOrigin> origin, PassRefPtr<StorageSyncManager> syncManager, unsigned quota)
-{
- RefPtr<StorageAreaImpl> area = adoptRef(new StorageAreaImpl(storageType, origin, syncManager, quota));
-
- // FIXME: If there's no backing storage for LocalStorage, the default WebKit behavior should be that of private browsing,
- // not silently ignoring it. https://bugs.webkit.org/show_bug.cgi?id=25894
- if (area->m_storageSyncManager) {
- area->m_storageAreaSync = StorageAreaSync::create(area->m_storageSyncManager, area.get(), area->m_securityOrigin->databaseIdentifier());
- ASSERT(area->m_storageAreaSync);
- }
-
- return area.release();
-}
-
-PassRefPtr<StorageAreaImpl> StorageAreaImpl::copy()
-{
- ASSERT(!m_isShutdown);
- return adoptRef(new StorageAreaImpl(this));
-}
-
-StorageAreaImpl::StorageAreaImpl(StorageAreaImpl* area)
- : m_storageType(area->m_storageType)
- , m_securityOrigin(area->m_securityOrigin)
- , m_storageMap(area->m_storageMap)
- , m_storageSyncManager(area->m_storageSyncManager)
-#ifndef NDEBUG
- , m_isShutdown(area->m_isShutdown)
-#endif
- , m_accessCount(0)
- , m_closeDatabaseTimer(this, &StorageAreaImpl::closeDatabaseTimerFired)
-{
- ASSERT(isMainThread());
- ASSERT(m_securityOrigin);
- ASSERT(m_storageMap);
- ASSERT(!m_isShutdown);
-}
-
-bool StorageAreaImpl::canAccessStorage(Frame* frame)
-{
- return frame && frame->page();
-}
-
-StorageType StorageAreaImpl::storageType() const
-{
- return m_storageType;
-}
-
-unsigned StorageAreaImpl::length()
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- return m_storageMap->length();
-}
-
-String StorageAreaImpl::key(unsigned index)
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- return m_storageMap->key(index);
-}
-
-String StorageAreaImpl::item(const String& key)
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- return m_storageMap->getItem(key);
-}
-
-void StorageAreaImpl::setItem(Frame* sourceFrame, const String& key, const String& value, bool& quotaException)
-{
- ASSERT(!m_isShutdown);
- ASSERT(!value.isNull());
- blockUntilImportComplete();
-
- String oldValue;
- RefPtr<StorageMap> newMap = m_storageMap->setItem(key, value, oldValue, quotaException);
- if (newMap)
- m_storageMap = newMap.release();
-
- if (quotaException)
- return;
-
- if (oldValue == value)
- return;
-
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleItemForSync(key, value);
-
- dispatchStorageEvent(key, oldValue, value, sourceFrame);
-}
-
-void StorageAreaImpl::removeItem(Frame* sourceFrame, const String& key)
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- String oldValue;
- RefPtr<StorageMap> newMap = m_storageMap->removeItem(key, oldValue);
- if (newMap)
- m_storageMap = newMap.release();
-
- if (oldValue.isNull())
- return;
-
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleItemForSync(key, String());
-
- dispatchStorageEvent(key, oldValue, String(), sourceFrame);
-}
-
-void StorageAreaImpl::clear(Frame* sourceFrame)
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- if (!m_storageMap->length())
- return;
-
- unsigned quota = m_storageMap->quota();
- m_storageMap = StorageMap::create(quota);
-
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleClear();
-
- dispatchStorageEvent(String(), String(), String(), sourceFrame);
-}
-
-bool StorageAreaImpl::contains(const String& key)
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- return m_storageMap->contains(key);
-}
-
-void StorageAreaImpl::importItems(const HashMap<String, String>& items)
-{
- ASSERT(!m_isShutdown);
-
- m_storageMap->importItems(items);
-}
-
-void StorageAreaImpl::close()
-{
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleFinalSync();
-
-#ifndef NDEBUG
- m_isShutdown = true;
-#endif
-}
-
-void StorageAreaImpl::clearForOriginDeletion()
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- if (m_storageMap->length()) {
- unsigned quota = m_storageMap->quota();
- m_storageMap = StorageMap::create(quota);
- }
-
- if (m_storageAreaSync) {
- m_storageAreaSync->scheduleClear();
- m_storageAreaSync->scheduleCloseDatabase();
- }
-}
-
-void StorageAreaImpl::sync()
-{
- ASSERT(!m_isShutdown);
- blockUntilImportComplete();
-
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleSync();
-}
-
-void StorageAreaImpl::blockUntilImportComplete() const
-{
- if (m_storageAreaSync)
- m_storageAreaSync->blockUntilImportComplete();
-}
-
-size_t StorageAreaImpl::memoryBytesUsedByCache()
-{
- return 0;
-}
-
-void StorageAreaImpl::incrementAccessCount()
-{
- m_accessCount++;
-
- if (m_closeDatabaseTimer.isActive())
- m_closeDatabaseTimer.stop();
-}
-
-void StorageAreaImpl::decrementAccessCount()
-{
- ASSERT(m_accessCount);
- --m_accessCount;
-
- if (!m_accessCount) {
- if (m_closeDatabaseTimer.isActive())
- m_closeDatabaseTimer.stop();
- m_closeDatabaseTimer.startOneShot(StorageTracker::tracker().storageDatabaseIdleInterval());
- }
-}
-
-void StorageAreaImpl::closeDatabaseTimerFired(Timer<StorageAreaImpl> *)
-{
- blockUntilImportComplete();
- if (m_storageAreaSync)
- m_storageAreaSync->scheduleCloseDatabase();
-}
-
-void StorageAreaImpl::closeDatabaseIfIdle()
-{
- if (m_closeDatabaseTimer.isActive()) {
- ASSERT(!m_accessCount);
- m_closeDatabaseTimer.stop();
-
- closeDatabaseTimerFired(&m_closeDatabaseTimer);
- }
-}
-
-void StorageAreaImpl::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame)
-{
- if (m_storageType == LocalStorage)
- StorageEventDispatcher::dispatchLocalStorageEvents(key, oldValue, newValue, m_securityOrigin.get(), sourceFrame);
- else
- StorageEventDispatcher::dispatchSessionStorageEvents(key, oldValue, newValue, m_securityOrigin.get(), sourceFrame);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageAreaImpl.h b/Source/WebCore/storage/StorageAreaImpl.h
deleted file mode 100644
index f384e0dd1..000000000
--- a/Source/WebCore/storage/StorageAreaImpl.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StorageAreaImpl_h
-#define StorageAreaImpl_h
-
-#include "StorageArea.h"
-#include "Timer.h"
-
-#include <wtf/HashMap.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class SecurityOrigin;
-class StorageMap;
-class StorageAreaSync;
-
-class StorageAreaImpl : public StorageArea {
-public:
- static PassRefPtr<StorageAreaImpl> create(StorageType, PassRefPtr<SecurityOrigin>, PassRefPtr<StorageSyncManager>, unsigned quota);
- virtual ~StorageAreaImpl();
-
- virtual unsigned length() override;
- virtual String key(unsigned index) override;
- virtual String item(const String& key) override;
- virtual void setItem(Frame* sourceFrame, const String& key, const String& value, bool& quotaException) override;
- virtual void removeItem(Frame* sourceFrame, const String& key) override;
- virtual void clear(Frame* sourceFrame) override;
- virtual bool contains(const String& key) override;
-
- virtual bool canAccessStorage(Frame* sourceFrame) override;
- virtual StorageType storageType() const override;
-
- virtual size_t memoryBytesUsedByCache() override;
-
- virtual void incrementAccessCount();
- virtual void decrementAccessCount();
- virtual void closeDatabaseIfIdle();
-
- PassRefPtr<StorageAreaImpl> copy();
- void close();
-
- // Only called from a background thread.
- void importItems(const HashMap<String, String>& items);
-
- // Used to clear a StorageArea and close db before backing db file is deleted.
- void clearForOriginDeletion();
-
- void sync();
-
-private:
- StorageAreaImpl(StorageType, PassRefPtr<SecurityOrigin>, PassRefPtr<StorageSyncManager>, unsigned quota);
- explicit StorageAreaImpl(StorageAreaImpl*);
-
- void blockUntilImportComplete() const;
- void closeDatabaseTimerFired(Timer<StorageAreaImpl>*);
-
- void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
-
- StorageType m_storageType;
- RefPtr<SecurityOrigin> m_securityOrigin;
- RefPtr<StorageMap> m_storageMap;
-
- RefPtr<StorageAreaSync> m_storageAreaSync;
- RefPtr<StorageSyncManager> m_storageSyncManager;
-
-#ifndef NDEBUG
- bool m_isShutdown;
-#endif
- unsigned m_accessCount;
- Timer<StorageAreaImpl> m_closeDatabaseTimer;
-};
-
-} // namespace WebCore
-
-#endif // StorageAreaImpl_h
diff --git a/Source/WebCore/storage/StorageAreaSync.cpp b/Source/WebCore/storage/StorageAreaSync.cpp
deleted file mode 100644
index eea5ebe6f..000000000
--- a/Source/WebCore/storage/StorageAreaSync.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "StorageAreaSync.h"
-
-#include "EventNames.h"
-#include "FileSystem.h"
-#include "HTMLElement.h"
-#include "SQLiteDatabaseTracker.h"
-#include "SQLiteFileSystem.h"
-#include "SQLiteStatement.h"
-#include "SQLiteTransaction.h"
-#include "SecurityOrigin.h"
-#include "StorageAreaImpl.h"
-#include "StorageSyncManager.h"
-#include "StorageTracker.h"
-#include "SuddenTermination.h"
-#include <wtf/Functional.h>
-#include <wtf/MainThread.h>
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-// If the StorageArea undergoes rapid changes, don't sync each change to disk.
-// Instead, queue up a batch of items to sync and actually do the sync at the following interval.
-static const double StorageSyncInterval = 1.0;
-
-// A sane limit on how many items we'll schedule to sync all at once. This makes it
-// much harder to starve the rest of LocalStorage and the OS's IO subsystem in general.
-static const int MaxiumItemsToSync = 100;
-
-inline StorageAreaSync::StorageAreaSync(PassRefPtr<StorageSyncManager> storageSyncManager, PassRefPtr<StorageAreaImpl> storageArea, const String& databaseIdentifier)
- : m_syncTimer(this, &StorageAreaSync::syncTimerFired)
- , m_itemsCleared(false)
- , m_finalSyncScheduled(false)
- , m_storageArea(storageArea)
- , m_syncManager(storageSyncManager)
- , m_databaseIdentifier(databaseIdentifier.isolatedCopy())
- , m_clearItemsWhileSyncing(false)
- , m_syncScheduled(false)
- , m_syncInProgress(false)
- , m_databaseOpenFailed(false)
- , m_syncCloseDatabase(false)
- , m_importComplete(false)
-{
- ASSERT(isMainThread());
- ASSERT(m_storageArea);
- ASSERT(m_syncManager);
-
- // FIXME: If it can't import, then the default WebKit behavior should be that of private browsing,
- // not silently ignoring it. https://bugs.webkit.org/show_bug.cgi?id=25894
- m_syncManager->dispatch(bind(&StorageAreaSync::performImport, this));
-}
-
-PassRefPtr<StorageAreaSync> StorageAreaSync::create(PassRefPtr<StorageSyncManager> storageSyncManager, PassRefPtr<StorageAreaImpl> storageArea, const String& databaseIdentifier)
-{
- RefPtr<StorageAreaSync> area = adoptRef(new StorageAreaSync(storageSyncManager, storageArea, databaseIdentifier));
-
- return area.release();
-}
-
-StorageAreaSync::~StorageAreaSync()
-{
- ASSERT(isMainThread());
- ASSERT(!m_syncTimer.isActive());
- ASSERT(m_finalSyncScheduled);
-}
-
-void StorageAreaSync::scheduleFinalSync()
-{
- ASSERT(isMainThread());
- // FIXME: We do this to avoid races, but it'd be better to make things safe without blocking.
- blockUntilImportComplete();
- m_storageArea = 0; // This is done in blockUntilImportComplete() but this is here as a form of documentation that we must be absolutely sure the ref count cycle is broken.
-
- if (m_syncTimer.isActive())
- m_syncTimer.stop();
- else {
- // The following is balanced by the call to enableSuddenTermination in the
- // syncTimerFired function.
- disableSuddenTermination();
- }
- // FIXME: This is synchronous. We should do it on the background process, but
- // we should do it safely.
- m_finalSyncScheduled = true;
- syncTimerFired(&m_syncTimer);
-
- m_syncManager->dispatch(bind(&StorageAreaSync::deleteEmptyDatabase, this));
-}
-
-void StorageAreaSync::scheduleItemForSync(const String& key, const String& value)
-{
- ASSERT(isMainThread());
- ASSERT(!m_finalSyncScheduled);
-
- m_changedItems.set(key, value);
- if (!m_syncTimer.isActive()) {
- m_syncTimer.startOneShot(StorageSyncInterval);
-
- // The following is balanced by the call to enableSuddenTermination in the
- // syncTimerFired function.
- disableSuddenTermination();
- }
-}
-
-void StorageAreaSync::scheduleClear()
-{
- ASSERT(isMainThread());
- ASSERT(!m_finalSyncScheduled);
-
- m_changedItems.clear();
- m_itemsCleared = true;
- if (!m_syncTimer.isActive()) {
- m_syncTimer.startOneShot(StorageSyncInterval);
-
- // The following is balanced by the call to enableSuddenTermination in the
- // syncTimerFired function.
- disableSuddenTermination();
- }
-}
-
-void StorageAreaSync::scheduleCloseDatabase()
-{
- ASSERT(isMainThread());
- ASSERT(!m_finalSyncScheduled);
-
- if (!m_database.isOpen())
- return;
-
- m_syncCloseDatabase = true;
-
- if (!m_syncTimer.isActive()) {
- m_syncTimer.startOneShot(StorageSyncInterval);
-
- // The following is balanced by the call to enableSuddenTermination in the
- // syncTimerFired function.
- disableSuddenTermination();
- }
-}
-
-void StorageAreaSync::syncTimerFired(Timer<StorageAreaSync>*)
-{
- ASSERT(isMainThread());
-
- bool partialSync = false;
- {
- MutexLocker locker(m_syncLock);
-
- // Do not schedule another sync if we're still trying to complete the
- // previous one. But, if we're shutting down, schedule it anyway.
- if (m_syncInProgress && !m_finalSyncScheduled) {
- ASSERT(!m_syncTimer.isActive());
- m_syncTimer.startOneShot(StorageSyncInterval);
- return;
- }
-
- if (m_itemsCleared) {
- m_itemsPendingSync.clear();
- m_clearItemsWhileSyncing = true;
- m_itemsCleared = false;
- }
-
- HashMap<String, String>::iterator changed_it = m_changedItems.begin();
- HashMap<String, String>::iterator changed_end = m_changedItems.end();
- for (int count = 0; changed_it != changed_end; ++count, ++changed_it) {
- if (count >= MaxiumItemsToSync && !m_finalSyncScheduled) {
- partialSync = true;
- break;
- }
- m_itemsPendingSync.set(changed_it->key.isolatedCopy(), changed_it->value.isolatedCopy());
- }
-
- if (partialSync) {
- // We can't do the fast path of simply clearing all items, so we'll need to manually
- // remove them one by one. Done under lock since m_itemsPendingSync is modified by
- // the background thread.
- HashMap<String, String>::iterator pending_it = m_itemsPendingSync.begin();
- HashMap<String, String>::iterator pending_end = m_itemsPendingSync.end();
- for (; pending_it != pending_end; ++pending_it)
- m_changedItems.remove(pending_it->key);
- }
-
- if (!m_syncScheduled) {
- m_syncScheduled = true;
-
- // The following is balanced by the call to enableSuddenTermination in the
- // performSync function.
- disableSuddenTermination();
-
- m_syncManager->dispatch(bind(&StorageAreaSync::performSync, this));
- }
- }
-
- if (partialSync) {
- // If we didn't finish syncing, then we need to finish the job later.
- ASSERT(!m_syncTimer.isActive());
- m_syncTimer.startOneShot(StorageSyncInterval);
- } else {
- // The following is balanced by the calls to disableSuddenTermination in the
- // scheduleItemForSync, scheduleClear, and scheduleFinalSync functions.
- enableSuddenTermination();
-
- m_changedItems.clear();
- }
-}
-
-void StorageAreaSync::openDatabase(OpenDatabaseParamType openingStrategy)
-{
- ASSERT(!isMainThread());
- ASSERT(!m_database.isOpen());
- ASSERT(!m_databaseOpenFailed);
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- String databaseFilename = m_syncManager->fullDatabaseFilename(m_databaseIdentifier);
-
- if (!fileExists(databaseFilename) && openingStrategy == SkipIfNonExistent)
- return;
-
- if (databaseFilename.isEmpty()) {
- LOG_ERROR("Filename for local storage database is empty - cannot open for persistent storage");
- markImported();
- m_databaseOpenFailed = true;
- return;
- }
-
- // A StorageTracker thread may have been scheduled to delete the db we're
- // reopening, so cancel possible deletion.
- StorageTracker::tracker().cancelDeletingOrigin(m_databaseIdentifier);
-
- if (!m_database.open(databaseFilename)) {
- LOG_ERROR("Failed to open database file %s for local storage", databaseFilename.utf8().data());
- markImported();
- m_databaseOpenFailed = true;
- return;
- }
-
- migrateItemTableIfNeeded();
-
- if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)")) {
- LOG_ERROR("Failed to create table ItemTable for local storage");
- markImported();
- m_databaseOpenFailed = true;
- return;
- }
-
- StorageTracker::tracker().setOriginDetails(m_databaseIdentifier, databaseFilename);
-}
-
-void StorageAreaSync::migrateItemTableIfNeeded()
-{
- if (!m_database.tableExists("ItemTable"))
- return;
-
- {
- SQLiteStatement query(m_database, "SELECT value FROM ItemTable LIMIT 1");
- // this query isn't ever executed.
- if (query.isColumnDeclaredAsBlob(0))
- return;
- }
-
- // alter table for backward compliance, change the value type from TEXT to BLOB.
- static const char* commands[] = {
- "DROP TABLE IF EXISTS ItemTable2",
- "CREATE TABLE ItemTable2 (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)",
- "INSERT INTO ItemTable2 SELECT * from ItemTable",
- "DROP TABLE ItemTable",
- "ALTER TABLE ItemTable2 RENAME TO ItemTable",
- 0,
- };
-
- SQLiteTransaction transaction(m_database, false);
- transaction.begin();
- for (size_t i = 0; commands[i]; ++i) {
- if (!m_database.executeCommand(commands[i])) {
- LOG_ERROR("Failed to migrate table ItemTable for local storage when executing: %s", commands[i]);
- transaction.rollback();
-
- // finally it will try to keep a backup of ItemTable for the future restoration.
- // NOTICE: this will essentially DELETE the current database, but that's better
- // than continually hitting this case and never being able to use the local storage.
- // if this is ever hit, it's definitely a bug.
- ASSERT_NOT_REACHED();
- if (!m_database.executeCommand("ALTER TABLE ItemTable RENAME TO Backup_ItemTable"))
- LOG_ERROR("Failed to save ItemTable after migration job failed.");
-
- return;
- }
- }
- transaction.commit();
-}
-
-void StorageAreaSync::performImport()
-{
- ASSERT(!isMainThread());
- ASSERT(!m_database.isOpen());
-
- openDatabase(SkipIfNonExistent);
- if (!m_database.isOpen()) {
- markImported();
- return;
- }
-
- SQLiteStatement query(m_database, "SELECT key, value FROM ItemTable");
- if (query.prepare() != SQLResultOk) {
- LOG_ERROR("Unable to select items from ItemTable for local storage");
- markImported();
- return;
- }
-
- HashMap<String, String> itemMap;
-
- int result = query.step();
- while (result == SQLResultRow) {
- itemMap.set(query.getColumnText(0), query.getColumnBlobAsString(1));
- result = query.step();
- }
-
- if (result != SQLResultDone) {
- LOG_ERROR("Error reading items from ItemTable for local storage");
- markImported();
- return;
- }
-
- m_storageArea->importItems(itemMap);
-
- markImported();
-}
-
-void StorageAreaSync::markImported()
-{
- MutexLocker locker(m_importLock);
- m_importComplete = true;
- m_importCondition.signal();
-}
-
-// FIXME: In the future, we should allow use of StorageAreas while it's importing (when safe to do so).
-// Blocking everything until the import is complete is by far the simplest and safest thing to do, but
-// there is certainly room for safe optimization: Key/length will never be able to make use of such an
-// optimization (since the order of iteration can change as items are being added). Get can return any
-// item currently in the map. Get/remove can work whether or not it's in the map, but we'll need a list
-// of items the import should not overwrite. Clear can also work, but it'll need to kill the import
-// job first.
-void StorageAreaSync::blockUntilImportComplete()
-{
- ASSERT(isMainThread());
-
- // Fast path. We set m_storageArea to 0 only after m_importComplete being true.
- if (!m_storageArea)
- return;
-
- MutexLocker locker(m_importLock);
- while (!m_importComplete)
- m_importCondition.wait(m_importLock);
- m_storageArea = 0;
-}
-
-void StorageAreaSync::sync(bool clearItems, const HashMap<String, String>& items)
-{
- ASSERT(!isMainThread());
-
- if (items.isEmpty() && !clearItems && !m_syncCloseDatabase)
- return;
- if (m_databaseOpenFailed)
- return;
-
- if (!m_database.isOpen() && m_syncCloseDatabase) {
- m_syncCloseDatabase = false;
- return;
- }
-
- if (!m_database.isOpen())
- openDatabase(CreateIfNonExistent);
- if (!m_database.isOpen())
- return;
-
- // Closing this db because it is about to be deleted by StorageTracker.
- // The delete will be cancelled if StorageAreaSync needs to reopen the db
- // to write new items created after the request to delete the db.
- if (m_syncCloseDatabase) {
- m_syncCloseDatabase = false;
- m_database.close();
- return;
- }
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- // If the clear flag is set, then we clear all items out before we write any new ones in.
- if (clearItems) {
- SQLiteStatement clear(m_database, "DELETE FROM ItemTable");
- if (clear.prepare() != SQLResultOk) {
- LOG_ERROR("Failed to prepare clear statement - cannot write to local storage database");
- return;
- }
-
- int result = clear.step();
- if (result != SQLResultDone) {
- LOG_ERROR("Failed to clear all items in the local storage database - %i", result);
- return;
- }
- }
-
- SQLiteStatement insert(m_database, "INSERT INTO ItemTable VALUES (?, ?)");
- if (insert.prepare() != SQLResultOk) {
- LOG_ERROR("Failed to prepare insert statement - cannot write to local storage database");
- return;
- }
-
- SQLiteStatement remove(m_database, "DELETE FROM ItemTable WHERE key=?");
- if (remove.prepare() != SQLResultOk) {
- LOG_ERROR("Failed to prepare delete statement - cannot write to local storage database");
- return;
- }
-
- HashMap<String, String>::const_iterator end = items.end();
-
- SQLiteTransaction transaction(m_database);
- transaction.begin();
- for (HashMap<String, String>::const_iterator it = items.begin(); it != end; ++it) {
- // Based on the null-ness of the second argument, decide whether this is an insert or a delete.
- SQLiteStatement& query = it->value.isNull() ? remove : insert;
-
- query.bindText(1, it->key);
-
- // If the second argument is non-null, we're doing an insert, so bind it as the value.
- if (!it->value.isNull())
- query.bindBlob(2, it->value);
-
- int result = query.step();
- if (result != SQLResultDone) {
- LOG_ERROR("Failed to update item in the local storage database - %i", result);
- break;
- }
-
- query.reset();
- }
- transaction.commit();
-}
-
-void StorageAreaSync::performSync()
-{
- ASSERT(!isMainThread());
-
- bool clearItems;
- HashMap<String, String> items;
- {
- MutexLocker locker(m_syncLock);
-
- ASSERT(m_syncScheduled);
-
- clearItems = m_clearItemsWhileSyncing;
- m_itemsPendingSync.swap(items);
-
- m_clearItemsWhileSyncing = false;
- m_syncScheduled = false;
- m_syncInProgress = true;
- }
-
- sync(clearItems, items);
-
- {
- MutexLocker locker(m_syncLock);
- m_syncInProgress = false;
- }
-
- // The following is balanced by the call to disableSuddenTermination in the
- // syncTimerFired function.
- enableSuddenTermination();
-}
-
-void StorageAreaSync::deleteEmptyDatabase()
-{
- ASSERT(!isMainThread());
- if (!m_database.isOpen())
- return;
-
- SQLiteStatement query(m_database, "SELECT COUNT(*) FROM ItemTable");
- if (query.prepare() != SQLResultOk) {
- LOG_ERROR("Unable to count number of rows in ItemTable for local storage");
- return;
- }
-
- int result = query.step();
- if (result != SQLResultRow) {
- LOG_ERROR("No results when counting number of rows in ItemTable for local storage");
- return;
- }
-
- int count = query.getColumnInt(0);
- if (!count) {
- query.finalize();
- m_database.close();
- if (StorageTracker::tracker().isActive())
- StorageTracker::tracker().deleteOriginWithIdentifier(m_databaseIdentifier);
- else {
- String databaseFilename = m_syncManager->fullDatabaseFilename(m_databaseIdentifier);
- if (!SQLiteFileSystem::deleteDatabaseFile(databaseFilename))
- LOG_ERROR("Failed to delete database file %s\n", databaseFilename.utf8().data());
- }
- }
-}
-
-void StorageAreaSync::scheduleSync()
-{
- syncTimerFired(&m_syncTimer);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageAreaSync.h b/Source/WebCore/storage/StorageAreaSync.h
deleted file mode 100644
index a5934b005..000000000
--- a/Source/WebCore/storage/StorageAreaSync.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StorageAreaSync_h
-#define StorageAreaSync_h
-
-#include "SQLiteDatabase.h"
-#include "Timer.h"
-#include <wtf/HashMap.h>
-#include <wtf/text/StringHash.h>
-
-namespace WebCore {
-
-class Frame;
-class StorageAreaImpl;
-class StorageSyncManager;
-
-class StorageAreaSync : public ThreadSafeRefCounted<StorageAreaSync> {
-public:
- static PassRefPtr<StorageAreaSync> create(PassRefPtr<StorageSyncManager>, PassRefPtr<StorageAreaImpl>, const String& databaseIdentifier);
- ~StorageAreaSync();
-
- void scheduleFinalSync();
- void blockUntilImportComplete();
-
- void scheduleItemForSync(const String& key, const String& value);
- void scheduleClear();
- void scheduleCloseDatabase();
-
- void scheduleSync();
-
-private:
- StorageAreaSync(PassRefPtr<StorageSyncManager>, PassRefPtr<StorageAreaImpl>, const String& databaseIdentifier);
-
- void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame);
-
- Timer<StorageAreaSync> m_syncTimer;
- HashMap<String, String> m_changedItems;
- bool m_itemsCleared;
-
- bool m_finalSyncScheduled;
-
- RefPtr<StorageAreaImpl> m_storageArea;
- RefPtr<StorageSyncManager> m_syncManager;
-
- // The database handle will only ever be opened and used on the background thread.
- SQLiteDatabase m_database;
-
- // The following members are subject to thread synchronization issues.
-public:
- // Called from the background thread
- void performImport();
- void performSync();
- void deleteEmptyDatabase();
-
-private:
- enum OpenDatabaseParamType {
- CreateIfNonExistent,
- SkipIfNonExistent
- };
-
- void syncTimerFired(Timer<StorageAreaSync>*);
- void openDatabase(OpenDatabaseParamType openingStrategy);
- void sync(bool clearItems, const HashMap<String, String>& items);
-
- const String m_databaseIdentifier;
-
- Mutex m_syncLock;
- HashMap<String, String> m_itemsPendingSync;
- bool m_clearItemsWhileSyncing;
- bool m_syncScheduled;
- bool m_syncInProgress;
- bool m_databaseOpenFailed;
-
- bool m_syncCloseDatabase;
-
- mutable Mutex m_importLock;
- mutable ThreadCondition m_importCondition;
- mutable bool m_importComplete;
- void markImported();
- void migrateItemTableIfNeeded();
-};
-
-} // namespace WebCore
-
-#endif // StorageAreaSync_h
diff --git a/Source/WebCore/storage/StorageEvent.cpp b/Source/WebCore/storage/StorageEvent.cpp
index e7d73d570..4fab01000 100644
--- a/Source/WebCore/storage/StorageEvent.cpp
+++ b/Source/WebCore/storage/StorageEvent.cpp
@@ -26,18 +26,13 @@
#include "config.h"
#include "StorageEvent.h"
-#include "EventNames.h"
#include "Storage.h"
namespace WebCore {
-StorageEventInit::StorageEventInit()
+Ref<StorageEvent> StorageEvent::createForBindings()
{
-}
-
-PassRefPtr<StorageEvent> StorageEvent::create()
-{
- return adoptRef(new StorageEvent);
+ return adoptRef(*new StorageEvent);
}
StorageEvent::StorageEvent()
@@ -48,14 +43,14 @@ StorageEvent::~StorageEvent()
{
}
-PassRefPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea)
+Ref<StorageEvent> StorageEvent::create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea)
{
- return adoptRef(new StorageEvent(type, key, oldValue, newValue, url, storageArea));
+ return adoptRef(*new StorageEvent(type, key, oldValue, newValue, url, storageArea));
}
-PassRefPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const StorageEventInit& initializer)
+Ref<StorageEvent> StorageEvent::create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
{
- return adoptRef(new StorageEvent(type, initializer));
+ return adoptRef(*new StorageEvent(type, initializer, isTrusted));
}
StorageEvent::StorageEvent(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea)
@@ -68,8 +63,8 @@ StorageEvent::StorageEvent(const AtomicString& type, const String& key, const St
{
}
-StorageEvent::StorageEvent(const AtomicString& type, const StorageEventInit& initializer)
- : Event(type, initializer)
+StorageEvent::StorageEvent(const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
+ : Event(type, initializer, isTrusted)
, m_key(initializer.key)
, m_oldValue(initializer.oldValue)
, m_newValue(initializer.newValue)
diff --git a/Source/WebCore/storage/StorageEvent.h b/Source/WebCore/storage/StorageEvent.h
index 783a626ce..ac18aac9f 100644
--- a/Source/WebCore/storage/StorageEvent.h
+++ b/Source/WebCore/storage/StorageEvent.h
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StorageEvent_h
-#define StorageEvent_h
+#pragma once
#include "Event.h"
#include <wtf/text/WTFString.h>
@@ -33,21 +32,20 @@ namespace WebCore {
class Storage;
-struct StorageEventInit : public EventInit {
- StorageEventInit();
-
- String key;
- String oldValue;
- String newValue;
- String url;
- RefPtr<Storage> storageArea;
-};
-
class StorageEvent : public Event {
public:
- static PassRefPtr<StorageEvent> create();
- static PassRefPtr<StorageEvent> create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea);
- static PassRefPtr<StorageEvent> create(const AtomicString&, const StorageEventInit&);
+ static Ref<StorageEvent> create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea);
+ static Ref<StorageEvent> createForBindings();
+
+ struct Init : EventInit {
+ String key;
+ String oldValue;
+ String newValue;
+ String url;
+ RefPtr<Storage> storageArea;
+ };
+
+ static Ref<StorageEvent> create(const AtomicString&, const Init&, IsTrusted = IsTrusted::No);
virtual ~StorageEvent();
const String& key() const { return m_key; }
@@ -61,12 +59,12 @@ public:
// Needed once we support init<blank>EventNS
// void initStorageEventNS(in DOMString namespaceURI, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString keyArg, in DOMString oldValueArg, in DOMString newValueArg, in DOMString urlArg, Storage storageAreaArg);
- virtual EventInterface eventInterface() const;
+ EventInterface eventInterface() const override;
private:
StorageEvent();
StorageEvent(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea);
- StorageEvent(const AtomicString&, const StorageEventInit&);
+ StorageEvent(const AtomicString&, const Init&, IsTrusted);
String m_key;
String m_oldValue;
@@ -76,5 +74,3 @@ private:
};
} // namespace WebCore
-
-#endif // StorageEvent_h
diff --git a/Source/WebCore/storage/StorageEvent.idl b/Source/WebCore/storage/StorageEvent.idl
index 742a56402..51dadc0eb 100644
--- a/Source/WebCore/storage/StorageEvent.idl
+++ b/Source/WebCore/storage/StorageEvent.idl
@@ -24,24 +24,32 @@
*/
[
- ConstructorTemplate=Event,
+ Constructor(DOMString type, optional StorageEventInit eventInitDict)
] interface StorageEvent : Event {
- [InitializedByEventConstructor] readonly attribute DOMString key;
- [InitializedByEventConstructor, TreatReturnedNullStringAs=Null] readonly attribute DOMString oldValue;
- [InitializedByEventConstructor, TreatReturnedNullStringAs=Null] readonly attribute DOMString newValue;
- [InitializedByEventConstructor] readonly attribute DOMString url;
- [InitializedByEventConstructor] readonly attribute Storage storageArea;
+ readonly attribute DOMString? key;
+ readonly attribute DOMString? oldValue;
+ readonly attribute DOMString? newValue;
+ readonly attribute USVString url;
+ readonly attribute Storage? storageArea;
- void initStorageEvent([Default=Undefined] optional DOMString typeArg,
- [Default=Undefined] optional boolean canBubbleArg,
- [Default=Undefined] optional boolean cancelableArg,
- [Default=Undefined] optional DOMString keyArg,
- [Default=Undefined,TreatNullAs=NullString] optional DOMString oldValueArg,
- [Default=Undefined,TreatNullAs=NullString] optional DOMString newValueArg,
- [Default=Undefined] optional DOMString urlArg,
- [Default=Undefined] optional Storage storageAreaArg);
+ // FIXME: Using "undefined" as default parameter value is wrong.
+ void initStorageEvent(optional DOMString typeArg = "undefined",
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional DOMString keyArg = "undefined",
+ optional DOMString? oldValueArg = null,
+ optional DOMString? newValueArg = null,
+ optional USVString urlArg = "undefined",
+ optional Storage? storageAreaArg = null);
// Needed once we support init<blank>EventNS
- // void initStorageEventNS(DOMString namespaceURI, DOMString typeArg, boolean canBubbleArg, boolean cancelableArg, DOMString keyArg, DOMString oldValueArg, DOMString newValueArg, DOMString urlArg, Storage storageAreaArg);
+ // void initStorageEventNS(DOMString namespaceURI, DOMString typeArg, boolean canBubbleArg, boolean cancelableArg, DOMString keyArg, DOMString oldValueArg, DOMString newValueArg, USVString urlArg, Storage? storageAreaArg);
};
+dictionary StorageEventInit : EventInit {
+ DOMString? key = null;
+ DOMString? oldValue = null;
+ DOMString? newValue = null;
+ USVString url = "";
+ Storage? storageArea = null;
+};
diff --git a/Source/WebCore/storage/StorageEventDispatcher.cpp b/Source/WebCore/storage/StorageEventDispatcher.cpp
index b4de9b857..ab89263d5 100644
--- a/Source/WebCore/storage/StorageEventDispatcher.cpp
+++ b/Source/WebCore/storage/StorageEventDispatcher.cpp
@@ -34,11 +34,13 @@
#include "Page.h"
#include "PageGroup.h"
#include "SecurityOrigin.h"
+#include "SecurityOriginData.h"
#include "StorageEvent.h"
+#include "StorageType.h"
namespace WebCore {
-void StorageEventDispatcher::dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, Frame* sourceFrame)
+void StorageEventDispatcher::dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData& securityOrigin, Frame* sourceFrame)
{
Page* page = sourceFrame->page();
if (!page)
@@ -48,14 +50,14 @@ void StorageEventDispatcher::dispatchSessionStorageEvents(const String& key, con
// Send events only to our page.
for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
+ if (sourceFrame != frame && frame->document()->securityOrigin().equal(securityOrigin.securityOrigin().ptr()))
frames.append(frame);
}
dispatchSessionStorageEventsToFrames(*page, frames, key, oldValue, newValue, sourceFrame->document()->url(), securityOrigin);
}
-void StorageEventDispatcher::dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, Frame* sourceFrame)
+void StorageEventDispatcher::dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData& securityOrigin, Frame* sourceFrame)
{
Page* page = sourceFrame->page();
if (!page)
@@ -64,10 +66,9 @@ void StorageEventDispatcher::dispatchLocalStorageEvents(const String& key, const
Vector<RefPtr<Frame>> frames;
// Send events to every page.
- const HashSet<Page*>& pages = page->group().pages();
- for (HashSet<Page*>::const_iterator it = pages.begin(), end = pages.end(); it != end; ++it) {
- for (Frame* frame = &(*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (sourceFrame != frame && frame->document()->securityOrigin()->equal(securityOrigin))
+ for (auto& pageInGroup : page->group().pages()) {
+ for (Frame* frame = &pageInGroup->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (sourceFrame != frame && frame->document()->securityOrigin().equal(securityOrigin.securityOrigin().ptr()))
frames.append(frame);
}
}
@@ -75,29 +76,26 @@ void StorageEventDispatcher::dispatchLocalStorageEvents(const String& key, const
dispatchLocalStorageEventsToFrames(page->group(), frames, key, oldValue, newValue, sourceFrame->document()->url(), securityOrigin);
}
-void StorageEventDispatcher::dispatchSessionStorageEventsToFrames(Page& page, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, SecurityOrigin* securityOrigin)
+void StorageEventDispatcher::dispatchSessionStorageEventsToFrames(Page& page, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData& securityOrigin)
{
- InspectorInstrumentation::didDispatchDOMStorageEvent(key, oldValue, newValue, SessionStorage, securityOrigin, &page);
+ InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, StorageType::Session, securityOrigin.securityOrigin().ptr());
- for (unsigned i = 0; i < frames.size(); ++i) {
- ExceptionCode ec = 0;
- Storage* storage = frames[i]->document()->domWindow()->sessionStorage(ec);
- if (!ec)
- frames[i]->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, storage));
+ for (auto& frame : frames) {
+ auto result = frame->document()->domWindow()->sessionStorage();
+ if (!result.hasException())
+ frame->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
}
}
-void StorageEventDispatcher::dispatchLocalStorageEventsToFrames(PageGroup& pageGroup, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, SecurityOrigin* securityOrigin)
+void StorageEventDispatcher::dispatchLocalStorageEventsToFrames(PageGroup& pageGroup, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData& securityOrigin)
{
- const HashSet<Page*>& pages = pageGroup.pages();
- for (HashSet<Page*>::const_iterator it = pages.begin(), end = pages.end(); it != end; ++it)
- InspectorInstrumentation::didDispatchDOMStorageEvent(key, oldValue, newValue, LocalStorage, securityOrigin, *it);
-
- for (unsigned i = 0; i < frames.size(); ++i) {
- ExceptionCode ec = 0;
- Storage* storage = frames[i]->document()->domWindow()->localStorage(ec);
- if (!ec)
- frames[i]->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, storage));
+ for (auto& page : pageGroup.pages())
+ InspectorInstrumentation::didDispatchDOMStorageEvent(*page, key, oldValue, newValue, StorageType::Local, securityOrigin.securityOrigin().ptr());
+
+ for (auto& frame : frames) {
+ auto result = frame->document()->domWindow()->localStorage();
+ if (!result.hasException())
+ frame->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
}
}
diff --git a/Source/WebCore/storage/StorageEventDispatcher.h b/Source/WebCore/storage/StorageEventDispatcher.h
index 056a2946c..6fa9510dd 100644
--- a/Source/WebCore/storage/StorageEventDispatcher.h
+++ b/Source/WebCore/storage/StorageEventDispatcher.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -27,8 +27,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StorageEventDispatcher_h
-#define StorageEventDispatcher_h
+#pragma once
#include <wtf/Forward.h>
#include <wtf/Vector.h>
@@ -38,20 +37,18 @@ namespace WebCore {
class Frame;
class Page;
class PageGroup;
-class SecurityOrigin;
+struct SecurityOriginData;
class StorageEventDispatcher {
public:
- static void dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, SecurityOrigin*, Frame* sourceFrame);
- static void dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, SecurityOrigin*, Frame* sourceFrame);
+ WEBCORE_EXPORT static void dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData&, Frame* sourceFrame);
+ WEBCORE_EXPORT static void dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData&, Frame* sourceFrame);
- static void dispatchSessionStorageEventsToFrames(Page&, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, SecurityOrigin*);
- static void dispatchLocalStorageEventsToFrames(PageGroup&, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, SecurityOrigin*);
+ WEBCORE_EXPORT static void dispatchSessionStorageEventsToFrames(Page&, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData&);
+ WEBCORE_EXPORT static void dispatchLocalStorageEventsToFrames(PageGroup&, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData&);
private:
// Do not instantiate.
StorageEventDispatcher();
};
} // namespace WebCore
-
-#endif // StorageEventDispatcher_h
diff --git a/Source/WebCore/storage/StorageMap.cpp b/Source/WebCore/storage/StorageMap.cpp
index fb7e43571..15598a8de 100644
--- a/Source/WebCore/storage/StorageMap.cpp
+++ b/Source/WebCore/storage/StorageMap.cpp
@@ -26,13 +26,13 @@
#include "config.h"
#include "StorageMap.h"
-#include <wtf/TemporaryChange.h>
+#include <wtf/SetForScope.h>
namespace WebCore {
-PassRefPtr<StorageMap> StorageMap::create(unsigned quota)
+Ref<StorageMap> StorageMap::create(unsigned quota)
{
- return adoptRef(new StorageMap(quota));
+ return adoptRef(*new StorageMap(quota));
}
StorageMap::StorageMap(unsigned quota)
@@ -43,12 +43,12 @@ StorageMap::StorageMap(unsigned quota)
{
}
-PassRefPtr<StorageMap> StorageMap::copy()
+Ref<StorageMap> StorageMap::copy()
{
- RefPtr<StorageMap> newMap = create(m_quotaSize);
+ Ref<StorageMap> newMap = create(m_quotaSize);
newMap->m_map = m_map;
newMap->m_currentLength = m_currentLength;
- return newMap.release();
+ return newMap;
}
void StorageMap::invalidateIterator()
@@ -99,7 +99,7 @@ String StorageMap::getItem(const String& key) const
return m_map.get(key);
}
-PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& value, String& oldValue, bool& quotaException)
+RefPtr<StorageMap> StorageMap::setItem(const String& key, const String& value, String& oldValue, bool& quotaException)
{
ASSERT(!value.isNull());
quotaException = false;
@@ -109,7 +109,7 @@ PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& valu
if (refCount() > 1) {
RefPtr<StorageMap> newStorageMap = copy();
newStorageMap->setItem(key, value, oldValue, quotaException);
- return newStorageMap.release();
+ return newStorageMap;
}
// Quota tracking. This is done in a couple of steps to keep the overflow tracking simple.
@@ -129,7 +129,7 @@ PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& valu
bool overQuota = newLength > m_quotaSize / sizeof(UChar);
if (m_quotaSize != noQuota && (overflow || overQuota)) {
quotaException = true;
- return 0;
+ return nullptr;
}
m_currentLength = newLength;
@@ -139,12 +139,12 @@ PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& valu
invalidateIterator();
- return 0;
+ return nullptr;
}
-PassRefPtr<StorageMap> StorageMap::setItemIgnoringQuota(const String& key, const String& value)
+RefPtr<StorageMap> StorageMap::setItemIgnoringQuota(const String& key, const String& value)
{
- TemporaryChange<unsigned> quotaSizeChange(m_quotaSize, noQuota);
+ SetForScope<unsigned> quotaSizeChange(m_quotaSize, static_cast<unsigned>(noQuota));
String oldValue;
bool quotaException;
@@ -152,17 +152,17 @@ PassRefPtr<StorageMap> StorageMap::setItemIgnoringQuota(const String& key, const
RefPtr<StorageMap> map = setItem(key, value, oldValue, quotaException);
ASSERT(!quotaException);
- return map.release();
+ return map;
}
-PassRefPtr<StorageMap> StorageMap::removeItem(const String& key, String& oldValue)
+RefPtr<StorageMap> StorageMap::removeItem(const String& key, String& oldValue)
{
// Implement copy-on-write semantics here. We're guaranteed that the only refs of StorageMaps belong to Storage objects
// so if more than one Storage object refs this map, copy it before mutating it.
if (refCount() > 1) {
RefPtr<StorageMap> newStorage = copy();
newStorage->removeItem(key, oldValue);
- return newStorage.release();
+ return newStorage;
}
oldValue = m_map.take(key);
@@ -174,7 +174,7 @@ PassRefPtr<StorageMap> StorageMap::removeItem(const String& key, String& oldValu
ASSERT(m_currentLength - oldValue.length() <= m_currentLength);
m_currentLength -= oldValue.length();
- return 0;
+ return nullptr;
}
bool StorageMap::contains(const String& key) const
@@ -184,9 +184,9 @@ bool StorageMap::contains(const String& key) const
void StorageMap::importItems(const HashMap<String, String>& items)
{
- for (HashMap<String, String>::const_iterator it = items.begin(), end = items.end(); it != end; ++it) {
- const String& key = it->key;
- const String& value = it->value;
+ for (auto& item : items) {
+ const String& key = item.key;
+ const String& value = item.value;
HashMap<String, String>::AddResult result = m_map.add(key, value);
ASSERT_UNUSED(result, result.isNewEntry); // True if the key didn't exist previously.
diff --git a/Source/WebCore/storage/StorageMap.h b/Source/WebCore/storage/StorageMap.h
index 594c2d8c3..fcdcca434 100644
--- a/Source/WebCore/storage/StorageMap.h
+++ b/Source/WebCore/storage/StorageMap.h
@@ -23,11 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StorageMap_h
-#define StorageMap_h
+#pragma once
#include <wtf/HashMap.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
@@ -37,27 +35,28 @@ namespace WebCore {
class StorageMap : public RefCounted<StorageMap> {
public:
// Quota size measured in bytes.
- static PassRefPtr<StorageMap> create(unsigned quotaSize);
+ WEBCORE_EXPORT static Ref<StorageMap> create(unsigned quotaSize);
- unsigned length() const;
- String key(unsigned index);
- String getItem(const String&) const;
- PassRefPtr<StorageMap> setItem(const String& key, const String& value, String& oldValue, bool& quotaException);
- PassRefPtr<StorageMap> setItemIgnoringQuota(const String& key, const String& value);
- PassRefPtr<StorageMap> removeItem(const String&, String& oldValue);
+ WEBCORE_EXPORT unsigned length() const;
+ WEBCORE_EXPORT String key(unsigned index);
+ WEBCORE_EXPORT String getItem(const String&) const;
+ WEBCORE_EXPORT RefPtr<StorageMap> setItem(const String& key, const String& value, String& oldValue, bool& quotaException);
+ WEBCORE_EXPORT RefPtr<StorageMap> setItemIgnoringQuota(const String& key, const String& value);
+ WEBCORE_EXPORT RefPtr<StorageMap> removeItem(const String&, String& oldValue);
- bool contains(const String& key) const;
+ WEBCORE_EXPORT bool contains(const String& key) const;
- void importItems(const HashMap<String, String>&);
+ WEBCORE_EXPORT void importItems(const HashMap<String, String>&);
const HashMap<String, String>& items() const { return m_map; }
unsigned quota() const { return m_quotaSize; }
- static const unsigned noQuota = UINT_MAX;
+ WEBCORE_EXPORT Ref<StorageMap> copy();
+
+ static const constexpr unsigned noQuota = UINT_MAX;
private:
explicit StorageMap(unsigned quota);
- PassRefPtr<StorageMap> copy();
void invalidateIterator();
void setIteratorToIndex(unsigned);
@@ -70,5 +69,3 @@ private:
};
} // namespace WebCore
-
-#endif // StorageMap_h
diff --git a/Source/WebCore/storage/StorageNamespace.h b/Source/WebCore/storage/StorageNamespace.h
index 1aef9e6fe..ead71a476 100644
--- a/Source/WebCore/storage/StorageNamespace.h
+++ b/Source/WebCore/storage/StorageNamespace.h
@@ -23,36 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StorageNamespace_h
-#define StorageNamespace_h
+#pragma once
#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
class Page;
-class PageGroup;
-class SecurityOrigin;
class StorageArea;
+struct SecurityOriginData;
class StorageNamespace : public RefCounted<StorageNamespace> {
public:
- static PassRefPtr<StorageNamespace> localStorageNamespace(PageGroup*);
- static PassRefPtr<StorageNamespace> transientLocalStorageNamespace(PageGroup*, SecurityOrigin*);
- static PassRefPtr<StorageNamespace> sessionStorageNamespace(Page*);
-
virtual ~StorageNamespace() { }
- virtual PassRefPtr<StorageArea> storageArea(PassRefPtr<SecurityOrigin>) = 0;
- virtual PassRefPtr<StorageNamespace> copy(Page* newPage) = 0;
- virtual void close() = 0;
- virtual void clearOriginForDeletion(SecurityOrigin*) = 0;
- virtual void clearAllOriginsForDeletion() = 0;
- virtual void sync() = 0;
- virtual void closeIdleLocalStorageDatabases() { }
+ virtual RefPtr<StorageArea> storageArea(const SecurityOriginData&) = 0;
+ virtual RefPtr<StorageNamespace> copy(Page* newPage) = 0;
};
} // namespace WebCore
-
-#endif // StorageNamespace_h
diff --git a/Source/WebCore/storage/StorageNamespaceImpl.cpp b/Source/WebCore/storage/StorageNamespaceImpl.cpp
deleted file mode 100644
index 2ac5db4a7..000000000
--- a/Source/WebCore/storage/StorageNamespaceImpl.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "StorageNamespaceImpl.h"
-
-#include "GroupSettings.h"
-#include "Page.h"
-#include "PageGroup.h"
-#include "SecurityOriginHash.h"
-#include "Settings.h"
-#include "StorageAreaImpl.h"
-#include "StorageMap.h"
-#include "StorageSyncManager.h"
-#include "StorageTracker.h"
-#include <wtf/MainThread.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/text/StringHash.h>
-
-namespace WebCore {
-
-typedef HashMap<String, StorageNamespace*> LocalStorageNamespaceMap;
-
-static LocalStorageNamespaceMap& localStorageNamespaceMap()
-{
- DEFINE_STATIC_LOCAL(LocalStorageNamespaceMap, localStorageNamespaceMap, ());
- return localStorageNamespaceMap;
-}
-
-PassRefPtr<StorageNamespace> StorageNamespaceImpl::localStorageNamespace(PageGroup* pageGroup)
-{
- // Need a page in this page group to query the settings for the local storage database path.
- // Having these parameters attached to the page settings is unfortunate since these settings are
- // not per-page (and, in fact, we simply grab the settings from some page at random), but
- // at this point we're stuck with it.
- Page* page = *pageGroup->pages().begin();
- const String& path = page->settings().localStorageDatabasePath();
- unsigned quota = pageGroup->groupSettings().localStorageQuotaBytes();
- const String lookupPath = path.isNull() ? emptyString() : path;
-
- LocalStorageNamespaceMap::AddResult result = localStorageNamespaceMap().add(lookupPath, nullptr);
- if (!result.isNewEntry)
- return result.iterator->value;
-
- RefPtr<StorageNamespace> storageNamespace = adoptRef(new StorageNamespaceImpl(LocalStorage, lookupPath, quota));
-
- result.iterator->value = storageNamespace.get();
- return storageNamespace.release();
-}
-
-PassRefPtr<StorageNamespace> StorageNamespaceImpl::sessionStorageNamespace(Page* page)
-{
- return adoptRef(new StorageNamespaceImpl(SessionStorage, String(), page->settings().sessionStorageQuota()));
-}
-
-PassRefPtr<StorageNamespace> StorageNamespaceImpl::transientLocalStorageNamespace(PageGroup* pageGroup, SecurityOrigin*)
-{
- // FIXME: A smarter implementation would create a special namespace type instead of just piggy-backing off
- // SessionStorageNamespace here.
- return StorageNamespaceImpl::sessionStorageNamespace(*pageGroup->pages().begin());
-}
-
-StorageNamespaceImpl::StorageNamespaceImpl(StorageType storageType, const String& path, unsigned quota)
- : m_storageType(storageType)
- , m_path(path.isolatedCopy())
- , m_syncManager(0)
- , m_quota(quota)
- , m_isShutdown(false)
-{
- if (m_storageType == LocalStorage && !m_path.isEmpty())
- m_syncManager = StorageSyncManager::create(m_path);
-}
-
-StorageNamespaceImpl::~StorageNamespaceImpl()
-{
- ASSERT(isMainThread());
-
- if (m_storageType == LocalStorage) {
- ASSERT(localStorageNamespaceMap().get(m_path) == this);
- localStorageNamespaceMap().remove(m_path);
- }
-
- if (!m_isShutdown)
- close();
-}
-
-PassRefPtr<StorageNamespace> StorageNamespaceImpl::copy(Page*)
-{
- ASSERT(isMainThread());
- ASSERT(!m_isShutdown);
- ASSERT(m_storageType == SessionStorage);
-
- RefPtr<StorageNamespaceImpl> newNamespace = adoptRef(new StorageNamespaceImpl(m_storageType, m_path, m_quota));
-
- StorageAreaMap::iterator end = m_storageAreaMap.end();
- for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i)
- newNamespace->m_storageAreaMap.set(i->key, i->value->copy());
- return newNamespace.release();
-}
-
-PassRefPtr<StorageArea> StorageNamespaceImpl::storageArea(PassRefPtr<SecurityOrigin> prpOrigin)
-{
- ASSERT(isMainThread());
- ASSERT(!m_isShutdown);
-
- RefPtr<SecurityOrigin> origin = prpOrigin;
- RefPtr<StorageAreaImpl> storageArea;
- if ((storageArea = m_storageAreaMap.get(origin)))
- return storageArea.release();
-
- storageArea = StorageAreaImpl::create(m_storageType, origin, m_syncManager, m_quota);
- m_storageAreaMap.set(origin.release(), storageArea);
- return storageArea.release();
-}
-
-void StorageNamespaceImpl::close()
-{
- ASSERT(isMainThread());
-
- if (m_isShutdown)
- return;
-
- // If we're session storage, we shouldn't need to do any work here.
- if (m_storageType == SessionStorage) {
- ASSERT(!m_syncManager);
- return;
- }
-
- StorageAreaMap::iterator end = m_storageAreaMap.end();
- for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
- it->value->close();
-
- if (m_syncManager)
- m_syncManager->close();
-
- m_isShutdown = true;
-}
-
-void StorageNamespaceImpl::clearOriginForDeletion(SecurityOrigin* origin)
-{
- ASSERT(isMainThread());
-
- RefPtr<StorageAreaImpl> storageArea = m_storageAreaMap.get(origin);
- if (storageArea)
- storageArea->clearForOriginDeletion();
-}
-
-void StorageNamespaceImpl::clearAllOriginsForDeletion()
-{
- ASSERT(isMainThread());
-
- StorageAreaMap::iterator end = m_storageAreaMap.end();
- for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
- it->value->clearForOriginDeletion();
-}
-
-void StorageNamespaceImpl::sync()
-{
- ASSERT(isMainThread());
- StorageAreaMap::iterator end = m_storageAreaMap.end();
- for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
- it->value->sync();
-}
-
-void StorageNamespaceImpl::closeIdleLocalStorageDatabases()
-{
- ASSERT(isMainThread());
- StorageAreaMap::iterator end = m_storageAreaMap.end();
- for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
- it->value->closeDatabaseIfIdle();
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageNamespaceImpl.h b/Source/WebCore/storage/StorageNamespaceImpl.h
deleted file mode 100644
index 8e77c338e..000000000
--- a/Source/WebCore/storage/StorageNamespaceImpl.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StorageNamespaceImpl_h
-#define StorageNamespaceImpl_h
-
-#include "SecurityOriginHash.h"
-#include "StorageArea.h"
-#include "StorageNamespace.h"
-#include <wtf/HashMap.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class StorageAreaImpl;
-
-class StorageNamespaceImpl : public StorageNamespace {
-public:
- static PassRefPtr<StorageNamespace> localStorageNamespace(PageGroup*);
- static PassRefPtr<StorageNamespace> transientLocalStorageNamespace(PageGroup*, SecurityOrigin*);
- static PassRefPtr<StorageNamespace> sessionStorageNamespace(Page*);
- virtual ~StorageNamespaceImpl();
-
- virtual PassRefPtr<StorageArea> storageArea(PassRefPtr<SecurityOrigin>) override;
- virtual PassRefPtr<StorageNamespace> copy(Page* newPage) override;
- virtual void close() override;
-
- // Not removing the origin's StorageArea from m_storageAreaMap because
- // we're just deleting the underlying db file. If an item is added immediately
- // after file deletion, we want the same StorageArea to eventually trigger
- // a sync and for StorageAreaSync to recreate the backing db file.
- virtual void clearOriginForDeletion(SecurityOrigin*) override;
- virtual void clearAllOriginsForDeletion() override;
- virtual void sync() override;
- virtual void closeIdleLocalStorageDatabases() override;
-
-private:
- StorageNamespaceImpl(StorageType, const String& path, unsigned quota);
-
- typedef HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageAreaImpl>> StorageAreaMap;
- StorageAreaMap m_storageAreaMap;
-
- StorageType m_storageType;
-
- // Only used if m_storageType == LocalStorage and the path was not "" in our constructor.
- String m_path;
- RefPtr<StorageSyncManager> m_syncManager;
-
- // The default quota for each new storage area.
- unsigned m_quota;
-
- bool m_isShutdown;
-};
-
-} // namespace WebCore
-
-#endif // StorageNamespaceImpl_h
diff --git a/Source/WebCore/storage/StorageNamespaceProvider.cpp b/Source/WebCore/storage/StorageNamespaceProvider.cpp
new file mode 100644
index 000000000..8c4af42f8
--- /dev/null
+++ b/Source/WebCore/storage/StorageNamespaceProvider.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StorageNamespaceProvider.h"
+
+#include "Document.h"
+#include "Page.h"
+#include "SecurityOriginData.h"
+#include "StorageArea.h"
+#include "StorageNamespace.h"
+
+namespace WebCore {
+
+// Suggested by the HTML5 spec.
+unsigned localStorageDatabaseQuotaInBytes = 5 * 1024 * 1024;
+
+StorageNamespaceProvider::StorageNamespaceProvider()
+{
+}
+
+StorageNamespaceProvider::~StorageNamespaceProvider()
+{
+ ASSERT(m_pages.isEmpty());
+}
+
+void StorageNamespaceProvider::addPage(Page& page)
+{
+ ASSERT(!m_pages.contains(&page));
+
+ m_pages.add(&page);
+}
+
+void StorageNamespaceProvider::removePage(Page& page)
+{
+ ASSERT(m_pages.contains(&page));
+
+ m_pages.remove(&page);
+}
+
+RefPtr<StorageArea> StorageNamespaceProvider::localStorageArea(Document& document)
+{
+ // This StorageNamespaceProvider was retrieved from the Document's Page,
+ // so the Document had better still actually have a Page.
+ ASSERT(document.page());
+
+ bool ephemeral = document.page()->usesEphemeralSession();
+ bool transient = !document.securityOrigin().canAccessLocalStorage(&document.topOrigin());
+
+ RefPtr<StorageNamespace> storageNamespace;
+
+ if (transient)
+ storageNamespace = &transientLocalStorageNamespace(document.topOrigin());
+ else if (ephemeral)
+ storageNamespace = document.page()->ephemeralLocalStorage();
+ else
+ storageNamespace = &localStorageNamespace();
+
+ return storageNamespace->storageArea(SecurityOriginData::fromSecurityOrigin(document.securityOrigin()));
+}
+
+StorageNamespace& StorageNamespaceProvider::localStorageNamespace()
+{
+ if (!m_localStorageNamespace)
+ m_localStorageNamespace = createLocalStorageNamespace(localStorageDatabaseQuotaInBytes);
+
+ return *m_localStorageNamespace;
+}
+
+StorageNamespace& StorageNamespaceProvider::transientLocalStorageNamespace(SecurityOrigin& securityOrigin)
+{
+ auto& slot = m_transientLocalStorageMap.add(&securityOrigin, nullptr).iterator->value;
+ if (!slot)
+ slot = createTransientLocalStorageNamespace(securityOrigin, localStorageDatabaseQuotaInBytes);
+
+ return *slot;
+}
+
+}
diff --git a/Source/WebCore/storage/StorageStrategy.h b/Source/WebCore/storage/StorageNamespaceProvider.h
index 4edd497df..1916ccb22 100644
--- a/Source/WebCore/storage/StorageStrategy.h
+++ b/Source/WebCore/storage/StorageNamespaceProvider.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,30 +23,49 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StorageStrategy_h
-#define StorageStrategy_h
+#pragma once
+#include "SecurityOriginHash.h"
#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
+class Document;
class Page;
-class PageGroup;
class SecurityOrigin;
+class StorageArea;
class StorageNamespace;
-class StorageStrategy {
+class StorageNamespaceProvider : public RefCounted<StorageNamespaceProvider> {
public:
- virtual PassRefPtr<StorageNamespace> localStorageNamespace(PageGroup*);
- virtual PassRefPtr<StorageNamespace> transientLocalStorageNamespace(PageGroup*, SecurityOrigin*);
- virtual PassRefPtr<StorageNamespace> sessionStorageNamespace(Page*);
+ WEBCORE_EXPORT StorageNamespaceProvider();
+ WEBCORE_EXPORT virtual ~StorageNamespaceProvider();
+
+ virtual RefPtr<StorageNamespace> createSessionStorageNamespace(Page&, unsigned quota) = 0;
+ virtual RefPtr<StorageNamespace> createEphemeralLocalStorageNamespace(Page&, unsigned quota) = 0;
+
+ RefPtr<StorageArea> localStorageArea(Document&);
+
+ void addPage(Page&);
+ void removePage(Page&);
protected:
- virtual ~StorageStrategy()
- {
- }
+ StorageNamespace* optionalLocalStorageNamespace() { return m_localStorageNamespace.get(); }
+
+private:
+ StorageNamespace& localStorageNamespace();
+ StorageNamespace& transientLocalStorageNamespace(SecurityOrigin&);
+
+ virtual RefPtr<StorageNamespace> createLocalStorageNamespace(unsigned quota) = 0;
+ virtual RefPtr<StorageNamespace> createTransientLocalStorageNamespace(SecurityOrigin&, unsigned quota) = 0;
+
+ HashSet<Page*> m_pages;
+
+ RefPtr<StorageNamespace> m_localStorageNamespace;
+ HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageNamespace>> m_transientLocalStorageMap;
};
} // namespace WebCore
-
-#endif // StorageStrategy_h
diff --git a/Source/WebCore/storage/StorageStrategy.cpp b/Source/WebCore/storage/StorageStrategy.cpp
deleted file mode 100644
index 88b84f417..000000000
--- a/Source/WebCore/storage/StorageStrategy.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "StorageStrategy.h"
-
-#include "StorageNamespaceImpl.h"
-
-namespace WebCore {
-
-PassRefPtr<StorageNamespace> StorageStrategy::localStorageNamespace(PageGroup* pageGroup)
-{
- return StorageNamespaceImpl::localStorageNamespace(pageGroup);
-}
-
-PassRefPtr<StorageNamespace> StorageStrategy::sessionStorageNamespace(Page* page)
-{
- return StorageNamespaceImpl::sessionStorageNamespace(page);
-}
-
-PassRefPtr<StorageNamespace> StorageStrategy::transientLocalStorageNamespace(PageGroup* pageGroup, SecurityOrigin* securityOrigin)
-{
- return StorageNamespaceImpl::transientLocalStorageNamespace(pageGroup, securityOrigin);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageSyncManager.cpp b/Source/WebCore/storage/StorageSyncManager.cpp
deleted file mode 100644
index 22197d579..000000000
--- a/Source/WebCore/storage/StorageSyncManager.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "StorageSyncManager.h"
-
-#include "EventNames.h"
-#include "FileSystem.h"
-#include "Frame.h"
-#include "FrameTree.h"
-#include "StorageThread.h"
-#include "Page.h"
-#include "PageGroup.h"
-#include "StorageAreaSync.h"
-#include <wtf/MainThread.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-PassRefPtr<StorageSyncManager> StorageSyncManager::create(const String& path)
-{
- return adoptRef(new StorageSyncManager(path));
-}
-
-StorageSyncManager::StorageSyncManager(const String& path)
- : m_thread(std::make_unique<StorageThread>())
- , m_path(path.isolatedCopy())
-{
- ASSERT(isMainThread());
- ASSERT(!m_path.isEmpty());
- m_thread->start();
-}
-
-StorageSyncManager::~StorageSyncManager()
-{
- ASSERT(isMainThread());
- ASSERT(!m_thread);
-}
-
-// Called on a background thread.
-String StorageSyncManager::fullDatabaseFilename(const String& databaseIdentifier)
-{
- if (!makeAllDirectories(m_path)) {
- LOG_ERROR("Unabled to create LocalStorage database path %s", m_path.utf8().data());
- return String();
- }
-
- return pathByAppendingComponent(m_path, databaseIdentifier + ".localstorage");
-}
-
-void StorageSyncManager::dispatch(const Function<void ()>& function)
-{
- ASSERT(isMainThread());
- ASSERT(m_thread);
-
- if (m_thread)
- m_thread->dispatch(function);
-}
-
-void StorageSyncManager::close()
-{
- ASSERT(isMainThread());
-
- if (m_thread) {
- m_thread->terminate();
- m_thread = nullptr;
- }
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageSyncManager.h b/Source/WebCore/storage/StorageSyncManager.h
deleted file mode 100644
index 64d010097..000000000
--- a/Source/WebCore/storage/StorageSyncManager.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StorageSyncManager_h
-#define StorageSyncManager_h
-
-#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class StorageThread;
-class StorageAreaSync;
-
-class StorageSyncManager : public RefCounted<StorageSyncManager> {
-public:
- static PassRefPtr<StorageSyncManager> create(const String& path);
- ~StorageSyncManager();
-
- void dispatch(const Function<void ()>&);
- void close();
-
-private:
- explicit StorageSyncManager(const String& path);
-
- std::unique_ptr<StorageThread> m_thread;
-
-// The following members are subject to thread synchronization issues
-public:
- // To be called from the background thread:
- String fullDatabaseFilename(const String& databaseIdentifier);
-
-private:
- String m_path;
-};
-
-} // namespace WebCore
-
-#endif // StorageSyncManager_h
diff --git a/Source/WebCore/storage/StorageThread.cpp b/Source/WebCore/storage/StorageThread.cpp
deleted file mode 100644
index 78fbe7032..000000000
--- a/Source/WebCore/storage/StorageThread.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "StorageThread.h"
-
-#include "StorageAreaSync.h"
-#include <wtf/AutodrainedPool.h>
-#include <wtf/HashSet.h>
-#include <wtf/MainThread.h>
-
-namespace WebCore {
-
-static HashSet<StorageThread*>& activeStorageThreads()
-{
- ASSERT(isMainThread());
- DEFINE_STATIC_LOCAL(HashSet<StorageThread*>, threads, ());
- return threads;
-}
-
-StorageThread::StorageThread()
- : m_threadID(0)
-{
- ASSERT(isMainThread());
-}
-
-StorageThread::~StorageThread()
-{
- ASSERT(isMainThread());
- ASSERT(!m_threadID);
-}
-
-bool StorageThread::start()
-{
- ASSERT(isMainThread());
- if (!m_threadID)
- m_threadID = createThread(StorageThread::threadEntryPointCallback, this, "WebCore: LocalStorage");
- activeStorageThreads().add(this);
- return m_threadID;
-}
-
-void StorageThread::threadEntryPointCallback(void* thread)
-{
- static_cast<StorageThread*>(thread)->threadEntryPoint();
-}
-
-void StorageThread::threadEntryPoint()
-{
- ASSERT(!isMainThread());
-
- while (auto function = m_queue.waitForMessage()) {
- AutodrainedPool pool;
- (*function)();
- }
-}
-
-void StorageThread::dispatch(const Function<void ()>& function)
-{
- ASSERT(isMainThread());
- ASSERT(!m_queue.killed() && m_threadID);
- m_queue.append(std::make_unique<Function<void ()>>(function));
-}
-
-void StorageThread::terminate()
-{
- ASSERT(isMainThread());
- ASSERT(!m_queue.killed() && m_threadID);
- activeStorageThreads().remove(this);
- // Even in weird, exceptional cases, don't wait on a nonexistent thread to terminate.
- if (!m_threadID)
- return;
-
- m_queue.append(std::make_unique<Function<void ()>>(bind(&StorageThread::performTerminate, this)));
- waitForThreadCompletion(m_threadID);
- ASSERT(m_queue.killed());
- m_threadID = 0;
-}
-
-void StorageThread::performTerminate()
-{
- ASSERT(!isMainThread());
- m_queue.kill();
-}
-
-void StorageThread::releaseFastMallocFreeMemoryInAllThreads()
-{
- HashSet<StorageThread*>& threads = activeStorageThreads();
-
- for (HashSet<StorageThread*>::iterator it = threads.begin(), end = threads.end(); it != end; ++it)
- (*it)->dispatch(bind(WTF::releaseFastMallocFreeMemory));
-}
-
-}
diff --git a/Source/WebCore/storage/StorageThread.h b/Source/WebCore/storage/StorageThread.h
deleted file mode 100644
index 8f092d080..000000000
--- a/Source/WebCore/storage/StorageThread.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StorageThread_h
-#define StorageThread_h
-
-#include <wtf/Functional.h>
-#include <wtf/HashSet.h>
-#include <wtf/MessageQueue.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/Threading.h>
-
-namespace WebCore {
-
-class StorageAreaSync;
-class StorageTask;
-
-class StorageThread {
- WTF_MAKE_NONCOPYABLE(StorageThread); WTF_MAKE_FAST_ALLOCATED;
-public:
- StorageThread();
- ~StorageThread();
-
- bool start();
- void terminate();
-
- void dispatch(const Function<void()>&);
-
- static void releaseFastMallocFreeMemoryInAllThreads();
-
-private:
- // Called on background thread.
- static void threadEntryPointCallback(void*);
- void threadEntryPoint();
-
- // Background thread part of the terminate procedure.
- void performTerminate();
-
- ThreadIdentifier m_threadID;
- MessageQueue<Function<void ()>> m_queue;
-};
-
-} // namespace WebCore
-
-#endif // StorageThread_h
diff --git a/Source/WebCore/storage/StorageTracker.cpp b/Source/WebCore/storage/StorageTracker.cpp
deleted file mode 100644
index dc236c3f0..000000000
--- a/Source/WebCore/storage/StorageTracker.cpp
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "StorageTracker.h"
-
-#include "DatabaseThread.h"
-#include "FileSystem.h"
-#include "Logging.h"
-#include "PageGroup.h"
-#include "SQLiteDatabaseTracker.h"
-#include "SQLiteFileSystem.h"
-#include "SQLiteStatement.h"
-#include "SecurityOrigin.h"
-#include "StorageThread.h"
-#include "StorageTrackerClient.h"
-#include "TextEncoding.h"
-#include <wtf/Functional.h>
-#include <wtf/MainThread.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/Vector.h>
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-static StorageTracker* storageTracker = 0;
-
-// If there is no document referencing a storage database, close the underlying database
-// after it has been idle for m_StorageDatabaseIdleInterval seconds.
-static const double DefaultStorageDatabaseIdleInterval = 300;
-
-void StorageTracker::initializeTracker(const String& storagePath, StorageTrackerClient* client)
-{
- ASSERT(isMainThread());
- ASSERT(!storageTracker || !storageTracker->m_client);
-
- if (!storageTracker)
- storageTracker = new StorageTracker(storagePath);
-
- storageTracker->m_client = client;
- storageTracker->m_needsInitialization = true;
-}
-
-void StorageTracker::internalInitialize()
-{
- m_needsInitialization = false;
-
- ASSERT(isMainThread());
-
- // Make sure text encoding maps have been built on the main thread, as the StorageTracker thread might try to do it there instead.
- // FIXME (<rdar://problem/9127819>): Is there a more explicit way of doing this besides accessing the UTF8Encoding?
- UTF8Encoding();
-
- storageTracker->setIsActive(true);
- storageTracker->m_thread->start();
- storageTracker->importOriginIdentifiers();
-}
-
-StorageTracker& StorageTracker::tracker()
-{
- if (!storageTracker)
- storageTracker = new StorageTracker("");
- if (storageTracker->m_needsInitialization)
- storageTracker->internalInitialize();
-
- return *storageTracker;
-}
-
-StorageTracker::StorageTracker(const String& storagePath)
- : m_storageDirectoryPath(storagePath.isolatedCopy())
- , m_client(0)
- , m_thread(std::make_unique<StorageThread>())
- , m_isActive(false)
- , m_needsInitialization(false)
- , m_StorageDatabaseIdleInterval(DefaultStorageDatabaseIdleInterval)
-{
-}
-
-void StorageTracker::setDatabaseDirectoryPath(const String& path)
-{
- MutexLocker locker(m_databaseMutex);
-
- if (m_database.isOpen())
- m_database.close();
-
- m_storageDirectoryPath = path.isolatedCopy();
-
- {
- MutexLocker locker(m_originSetMutex);
- m_originSet.clear();
- }
-
- if (!m_isActive)
- return;
-
- importOriginIdentifiers();
-}
-
-String StorageTracker::databaseDirectoryPath() const
-{
- return m_storageDirectoryPath.isolatedCopy();
-}
-
-String StorageTracker::trackerDatabasePath()
-{
- ASSERT(!m_databaseMutex.tryLock());
- return SQLiteFileSystem::appendDatabaseFileNameToPath(m_storageDirectoryPath, "StorageTracker.db");
-}
-
-void StorageTracker::openTrackerDatabase(bool createIfDoesNotExist)
-{
- ASSERT(m_isActive);
- ASSERT(!isMainThread());
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- ASSERT(!m_databaseMutex.tryLock());
-
- if (m_database.isOpen())
- return;
-
- String databasePath = trackerDatabasePath();
-
- if (!SQLiteFileSystem::ensureDatabaseFileExists(databasePath, createIfDoesNotExist)) {
- if (createIfDoesNotExist)
- LOG_ERROR("Failed to create database file '%s'", databasePath.ascii().data());
- return;
- }
-
- if (!m_database.open(databasePath)) {
- LOG_ERROR("Failed to open databasePath %s.", databasePath.ascii().data());
- return;
- }
-
- m_database.disableThreadingChecks();
-
- if (!m_database.tableExists("Origins")) {
- if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, path TEXT);"))
- LOG_ERROR("Failed to create Origins table.");
- }
-}
-
-void StorageTracker::importOriginIdentifiers()
-{
- if (!m_isActive)
- return;
-
- ASSERT(isMainThread());
- ASSERT(m_thread);
-
- m_thread->dispatch(bind(&StorageTracker::syncImportOriginIdentifiers, this));
-}
-
-void StorageTracker::finishedImportingOriginIdentifiers()
-{
- MutexLocker locker(m_databaseMutex);
- if (m_client)
- m_client->didFinishLoadingOrigins();
-}
-
-void StorageTracker::syncImportOriginIdentifiers()
-{
- ASSERT(m_isActive);
-
- ASSERT(!isMainThread());
-
- {
- MutexLocker locker(m_databaseMutex);
-
- // Don't force creation of StorageTracker's db just because a tracker
- // was initialized. It will be created if local storage dbs are found
- // by syncFileSystemAndTrackerDatabse() or the next time a local storage
- // db is created by StorageAreaSync.
- openTrackerDatabase(false);
-
- if (m_database.isOpen()) {
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- SQLiteStatement statement(m_database, "SELECT origin FROM Origins");
- if (statement.prepare() != SQLResultOk) {
- LOG_ERROR("Failed to prepare statement.");
- return;
- }
-
- int result;
-
- {
- MutexLocker lockOrigins(m_originSetMutex);
- while ((result = statement.step()) == SQLResultRow)
- m_originSet.add(statement.getColumnText(0).isolatedCopy());
- }
-
- if (result != SQLResultDone) {
- LOG_ERROR("Failed to read in all origins from the database.");
- return;
- }
- }
- }
-
- syncFileSystemAndTrackerDatabase();
-
- {
- MutexLocker locker(m_clientMutex);
-
- if (m_client) {
- MutexLocker locker(m_originSetMutex);
- OriginSet::const_iterator end = m_originSet.end();
- for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
- m_client->dispatchDidModifyOrigin(*it);
- }
- }
-
- callOnMainThread(bind(&StorageTracker::finishedImportingOriginIdentifiers, this));
-}
-
-void StorageTracker::syncFileSystemAndTrackerDatabase()
-{
- ASSERT(!isMainThread());
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- ASSERT(m_isActive);
-
- Vector<String> paths;
- {
- MutexLocker locker(m_databaseMutex);
- paths = listDirectory(m_storageDirectoryPath, "*.localstorage");
- }
-
- // Use a copy of m_originSet to find expired entries and to schedule their
- // deletions from disk and from m_originSet.
- OriginSet originSetCopy;
- {
- MutexLocker locker(m_originSetMutex);
- for (OriginSet::const_iterator it = m_originSet.begin(), end = m_originSet.end(); it != end; ++it)
- originSetCopy.add((*it).isolatedCopy());
- }
-
- // Add missing StorageTracker records.
- OriginSet foundOrigins;
- String fileExtension = ASCIILiteral(".localstorage");
-
- for (Vector<String>::const_iterator it = paths.begin(), end = paths.end(); it != end; ++it) {
- const String& path = *it;
-
- if (path.length() > fileExtension.length() && path.endsWith(fileExtension, true)) {
- String file = pathGetFileName(path);
- String originIdentifier = file.substring(0, file.length() - fileExtension.length());
- if (!originSetCopy.contains(originIdentifier))
- syncSetOriginDetails(originIdentifier, path);
-
- foundOrigins.add(originIdentifier);
- }
- }
-
- // Delete stale StorageTracker records.
- for (OriginSet::const_iterator it = originSetCopy.begin(), end = originSetCopy.end(); it != end; ++it) {
- const String& originIdentifier = *it;
- if (foundOrigins.contains(originIdentifier))
- continue;
-
- callOnMainThread(bind(&StorageTracker::deleteOriginWithIdentifier, this, originIdentifier.isolatedCopy()));
- }
-}
-
-void StorageTracker::setOriginDetails(const String& originIdentifier, const String& databaseFile)
-{
- if (!m_isActive)
- return;
-
- {
- MutexLocker locker(m_originSetMutex);
-
- if (m_originSet.contains(originIdentifier))
- return;
-
- m_originSet.add(originIdentifier);
- }
-
- Function<void ()> function = bind(&StorageTracker::syncSetOriginDetails, this, originIdentifier.isolatedCopy(), databaseFile.isolatedCopy());
-
- if (isMainThread()) {
- ASSERT(m_thread);
- m_thread->dispatch(function);
- } else {
- // FIXME: This weird ping-ponging was done to fix a deadlock. We should figure out a cleaner way to avoid it instead.
- callOnMainThread(bind(&StorageThread::dispatch, m_thread.get(), function));
- }
-}
-
-void StorageTracker::syncSetOriginDetails(const String& originIdentifier, const String& databaseFile)
-{
- ASSERT(!isMainThread());
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- MutexLocker locker(m_databaseMutex);
-
- openTrackerDatabase(true);
-
- if (!m_database.isOpen())
- return;
-
- SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)");
- if (statement.prepare() != SQLResultOk) {
- LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.ascii().data());
- return;
- }
-
- statement.bindText(1, originIdentifier);
- statement.bindText(2, databaseFile);
-
- if (statement.step() != SQLResultDone)
- LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.ascii().data());
-
- {
- MutexLocker locker(m_originSetMutex);
- if (!m_originSet.contains(originIdentifier))
- m_originSet.add(originIdentifier);
- }
-
- {
- MutexLocker locker(m_clientMutex);
- if (m_client)
- m_client->dispatchDidModifyOrigin(originIdentifier);
- }
-}
-
-void StorageTracker::origins(Vector<RefPtr<SecurityOrigin>>& result)
-{
- ASSERT(m_isActive);
-
- if (!m_isActive)
- return;
-
- MutexLocker locker(m_originSetMutex);
-
- for (OriginSet::const_iterator it = m_originSet.begin(), end = m_originSet.end(); it != end; ++it)
- result.append(SecurityOrigin::createFromDatabaseIdentifier(*it));
-}
-
-void StorageTracker::deleteAllOrigins()
-{
- ASSERT(m_isActive);
- ASSERT(isMainThread());
- ASSERT(m_thread);
-
- if (!m_isActive)
- return;
-
- {
- MutexLocker locker(m_originSetMutex);
- willDeleteAllOrigins();
- m_originSet.clear();
- }
-
- PageGroup::clearLocalStorageForAllOrigins();
-
- m_thread->dispatch(bind(&StorageTracker::syncDeleteAllOrigins, this));
-}
-
-void StorageTracker::syncDeleteAllOrigins()
-{
- ASSERT(!isMainThread());
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- MutexLocker locker(m_databaseMutex);
-
- openTrackerDatabase(false);
- if (!m_database.isOpen())
- return;
-
- SQLiteStatement statement(m_database, "SELECT origin, path FROM Origins");
- if (statement.prepare() != SQLResultOk) {
- LOG_ERROR("Failed to prepare statement.");
- return;
- }
-
- int result;
- while ((result = statement.step()) == SQLResultRow) {
- if (!canDeleteOrigin(statement.getColumnText(0)))
- continue;
-
- SQLiteFileSystem::deleteDatabaseFile(statement.getColumnText(1));
-
- {
- MutexLocker locker(m_clientMutex);
- if (m_client)
- m_client->dispatchDidModifyOrigin(statement.getColumnText(0));
- }
- }
-
- if (result != SQLResultDone)
- LOG_ERROR("Failed to read in all origins from the database.");
-
- if (m_database.isOpen()) {
-#if PLATFORM(IOS)
- SQLiteFileSystem::truncateDatabaseFile(m_database.sqlite3Handle());
-#endif
- m_database.close();
- }
-
-#if !PLATFORM(IOS)
- if (!SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath())) {
- // In the case where it is not possible to delete the database file (e.g some other program
- // like a virus scanner is accessing it), make sure to remove all entries.
- openTrackerDatabase(false);
- if (!m_database.isOpen())
- return;
- SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins");
- if (deleteStatement.prepare() != SQLResultOk) {
- LOG_ERROR("Unable to prepare deletion of all origins");
- return;
- }
- if (!deleteStatement.executeCommand()) {
- LOG_ERROR("Unable to execute deletion of all origins");
- return;
- }
- }
- SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_storageDirectoryPath);
-#endif
-}
-
-void StorageTracker::deleteOriginWithIdentifier(const String& originIdentifier)
-{
- deleteOrigin(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier).get());
-}
-
-void StorageTracker::deleteOrigin(SecurityOrigin* origin)
-{
- ASSERT(m_isActive);
- ASSERT(isMainThread());
- ASSERT(m_thread);
-
- if (!m_isActive)
- return;
-
- // Before deleting database, we need to clear in-memory local storage data
- // in StorageArea, and to close the StorageArea db. It's possible for an
- // item to be added immediately after closing the db and cause StorageAreaSync
- // to reopen the db before the db is deleted by a StorageTracker thread.
- // In this case, reopening the db in StorageAreaSync will cancel a pending
- // StorageTracker db deletion.
- PageGroup::clearLocalStorageForOrigin(origin);
-
- String originId = origin->databaseIdentifier();
-
- {
- MutexLocker locker(m_originSetMutex);
- willDeleteOrigin(originId);
- m_originSet.remove(originId);
- }
-
- m_thread->dispatch(bind(&StorageTracker::syncDeleteOrigin, this, originId.isolatedCopy()));
-}
-
-void StorageTracker::syncDeleteOrigin(const String& originIdentifier)
-{
- ASSERT(!isMainThread());
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- MutexLocker locker(m_databaseMutex);
-
- if (!canDeleteOrigin(originIdentifier)) {
- LOG_ERROR("Attempted to delete origin '%s' while it was being created\n", originIdentifier.ascii().data());
- return;
- }
-
- openTrackerDatabase(false);
- if (!m_database.isOpen())
- return;
-
- String path = databasePathForOrigin(originIdentifier);
- if (path.isEmpty()) {
- // It is possible to get a request from the API to delete the storage for an origin that
- // has no such storage.
- return;
- }
-
- SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins where origin=?");
- if (deleteStatement.prepare() != SQLResultOk) {
- LOG_ERROR("Unable to prepare deletion of origin '%s'", originIdentifier.ascii().data());
- return;
- }
- deleteStatement.bindText(1, originIdentifier);
- if (!deleteStatement.executeCommand()) {
- LOG_ERROR("Unable to execute deletion of origin '%s'", originIdentifier.ascii().data());
- return;
- }
-
- SQLiteFileSystem::deleteDatabaseFile(path);
-
- bool shouldDeleteTrackerFiles = false;
- {
- MutexLocker locker(m_originSetMutex);
- m_originSet.remove(originIdentifier);
- shouldDeleteTrackerFiles = m_originSet.isEmpty();
- }
-
- if (shouldDeleteTrackerFiles) {
-#if PLATFORM(IOS)
- SQLiteFileSystem::truncateDatabaseFile(m_database.sqlite3Handle());
-#endif
- m_database.close();
-#if !PLATFORM(IOS)
- SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath());
- SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_storageDirectoryPath);
-#endif
- }
-
- {
- MutexLocker locker(m_clientMutex);
- if (m_client)
- m_client->dispatchDidModifyOrigin(originIdentifier);
- }
-}
-
-void StorageTracker::willDeleteAllOrigins()
-{
- ASSERT(!m_originSetMutex.tryLock());
-
- OriginSet::const_iterator end = m_originSet.end();
- for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
- m_originsBeingDeleted.add((*it).isolatedCopy());
-}
-
-void StorageTracker::willDeleteOrigin(const String& originIdentifier)
-{
- ASSERT(isMainThread());
- ASSERT(!m_originSetMutex.tryLock());
-
- m_originsBeingDeleted.add(originIdentifier);
-}
-
-bool StorageTracker::canDeleteOrigin(const String& originIdentifier)
-{
- ASSERT(!m_databaseMutex.tryLock());
- MutexLocker locker(m_originSetMutex);
- return m_originsBeingDeleted.contains(originIdentifier);
-}
-
-void StorageTracker::cancelDeletingOrigin(const String& originIdentifier)
-{
- if (!m_isActive)
- return;
-
- MutexLocker locker(m_databaseMutex);
- {
- MutexLocker locker(m_originSetMutex);
- if (!m_originsBeingDeleted.isEmpty())
- m_originsBeingDeleted.remove(originIdentifier);
- }
-}
-
-bool StorageTracker::isActive()
-{
- return m_isActive;
-}
-
-void StorageTracker::setIsActive(bool flag)
-{
- m_isActive = flag;
-}
-
-String StorageTracker::databasePathForOrigin(const String& originIdentifier)
-{
- ASSERT(!m_databaseMutex.tryLock());
- ASSERT(m_isActive);
-
- if (!m_database.isOpen())
- return String();
-
- SQLiteTransactionInProgressAutoCounter transactionCounter;
-
- SQLiteStatement pathStatement(m_database, "SELECT path FROM Origins WHERE origin=?");
- if (pathStatement.prepare() != SQLResultOk) {
- LOG_ERROR("Unable to prepare selection of path for origin '%s'", originIdentifier.ascii().data());
- return String();
- }
- pathStatement.bindText(1, originIdentifier);
- int result = pathStatement.step();
- if (result != SQLResultRow)
- return String();
-
- return pathStatement.getColumnText(0);
-}
-
-long long StorageTracker::diskUsageForOrigin(SecurityOrigin* origin)
-{
- if (!m_isActive)
- return 0;
-
- MutexLocker locker(m_databaseMutex);
-
- String path = databasePathForOrigin(origin->databaseIdentifier());
- if (path.isEmpty())
- return 0;
-
- return SQLiteFileSystem::getDatabaseFileSize(path);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageTracker.h b/Source/WebCore/storage/StorageTracker.h
deleted file mode 100644
index 98b5b5681..000000000
--- a/Source/WebCore/storage/StorageTracker.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StorageTracker_h
-#define StorageTracker_h
-
-#include "SQLiteDatabase.h"
-#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
-#include <wtf/text/StringHash.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class StorageTask;
-class StorageThread;
-class SecurityOrigin;
-class StorageTrackerClient;
-
-class StorageTracker {
- WTF_MAKE_NONCOPYABLE(StorageTracker);
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static void initializeTracker(const String& storagePath, StorageTrackerClient*);
- static StorageTracker& tracker();
-
- void setDatabaseDirectoryPath(const String&);
- String databaseDirectoryPath() const;
-
- void setOriginDetails(const String& originIdentifier, const String& databaseFile);
-
- void deleteAllOrigins();
- void deleteOrigin(SecurityOrigin*);
- void deleteOriginWithIdentifier(const String& originIdentifier);
- void origins(Vector<RefPtr<SecurityOrigin>>& result);
- long long diskUsageForOrigin(SecurityOrigin*);
-
- void cancelDeletingOrigin(const String& originIdentifier);
-
- bool isActive();
-
- double storageDatabaseIdleInterval() { return m_StorageDatabaseIdleInterval; }
- void setStorageDatabaseIdleInterval(double interval) { m_StorageDatabaseIdleInterval = interval; }
-
- void syncFileSystemAndTrackerDatabase();
-
-private:
- explicit StorageTracker(const String& storagePath);
-
- void internalInitialize();
-
- String trackerDatabasePath();
- void openTrackerDatabase(bool createIfDoesNotExist);
-
- void importOriginIdentifiers();
- void finishedImportingOriginIdentifiers();
-
- void deleteTrackerFiles();
- String databasePathForOrigin(const String& originIdentifier);
-
- bool canDeleteOrigin(const String& originIdentifier);
- void willDeleteOrigin(const String& originIdentifier);
- void willDeleteAllOrigins();
-
- void originFilePaths(Vector<String>& paths);
-
- void setIsActive(bool);
-
- // Sync to disk on background thread.
- void syncDeleteAllOrigins();
- void syncDeleteOrigin(const String& originIdentifier);
- void syncSetOriginDetails(const String& originIdentifier, const String& databaseFile);
- void syncImportOriginIdentifiers();
-
- // Mutex for m_database and m_storageDirectoryPath.
- Mutex m_databaseMutex;
- SQLiteDatabase m_database;
- String m_storageDirectoryPath;
-
- Mutex m_clientMutex;
- StorageTrackerClient* m_client;
-
- // Guard for m_originSet and m_originsBeingDeleted.
- Mutex m_originSetMutex;
- typedef HashSet<String> OriginSet;
- OriginSet m_originSet;
- OriginSet m_originsBeingDeleted;
-
- std::unique_ptr<StorageThread> m_thread;
-
- bool m_isActive;
- bool m_needsInitialization;
- double m_StorageDatabaseIdleInterval;
-};
-
-} // namespace WebCore
-
-#endif // StorageTracker_h
diff --git a/Source/WebCore/storage/StorageTrackerClient.h b/Source/WebCore/storage/StorageTrackerClient.h
deleted file mode 100644
index 71a6029fa..000000000
--- a/Source/WebCore/storage/StorageTrackerClient.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StorageTrackerClient_h
-#define StorageTrackerClient_h
-
-#include <wtf/Forward.h>
-
-namespace WebCore {
-
-class StorageTrackerClient {
-public:
- virtual ~StorageTrackerClient() { }
- virtual void dispatchDidModifyOrigin(const String& originIdentifier) = 0;
- virtual void didFinishLoadingOrigins() = 0;
-};
-
-} // namespace WebCore
-
-#endif // StorageTrackerClient_h
diff --git a/Source/WebCore/storage/StorageNamespace.cpp b/Source/WebCore/storage/StorageType.h
index 2bbbedc79..58133f89c 100644
--- a/Source/WebCore/storage/StorageNamespace.cpp
+++ b/Source/WebCore/storage/StorageType.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,27 +23,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "StorageNamespace.h"
-
-#include "PlatformStrategies.h"
-#include "StorageStrategy.h"
+#pragma once
namespace WebCore {
-PassRefPtr<StorageNamespace> StorageNamespace::localStorageNamespace(PageGroup* pageGroup)
-{
- return platformStrategies()->storageStrategy()->localStorageNamespace(pageGroup);
-}
+enum class StorageType {
+ Session,
+ Local,
+ EphemeralLocal,
+ TransientLocal,
+};
-PassRefPtr<StorageNamespace> StorageNamespace::transientLocalStorageNamespace(PageGroup* pageGroup, SecurityOrigin* securityOrigin)
+inline bool isLocalStorage(StorageType storageType)
{
- return platformStrategies()->storageStrategy()->transientLocalStorageNamespace(pageGroup, securityOrigin);
+ return storageType == StorageType::Local || storageType == StorageType::TransientLocal || storageType == StorageType::EphemeralLocal;
}
-PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace(Page* page)
+inline bool isPersistentLocalStorage(StorageType storageType)
{
- return platformStrategies()->storageStrategy()->sessionStorageNamespace(page);
+ return storageType == StorageType::Local || storageType == StorageType::TransientLocal;
}
} // namespace WebCore