summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/icon
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/icon
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/loader/icon')
-rw-r--r--Source/WebCore/loader/icon/IconController.cpp170
-rw-r--r--Source/WebCore/loader/icon/IconController.h21
-rw-r--r--Source/WebCore/loader/icon/IconDatabase.cpp559
-rw-r--r--Source/WebCore/loader/icon/IconDatabase.h187
-rw-r--r--Source/WebCore/loader/icon/IconDatabaseBase.cpp8
-rw-r--r--Source/WebCore/loader/icon/IconDatabaseBase.h76
-rw-r--r--Source/WebCore/loader/icon/IconDatabaseClient.h8
-rw-r--r--Source/WebCore/loader/icon/IconLoader.cpp84
-rw-r--r--Source/WebCore/loader/icon/IconLoader.h21
-rw-r--r--Source/WebCore/loader/icon/IconRecord.cpp8
-rw-r--r--Source/WebCore/loader/icon/IconRecord.h15
-rw-r--r--Source/WebCore/loader/icon/PageURLRecord.cpp16
-rw-r--r--Source/WebCore/loader/icon/PageURLRecord.h16
13 files changed, 530 insertions, 659 deletions
diff --git a/Source/WebCore/loader/icon/IconController.cpp b/Source/WebCore/loader/icon/IconController.cpp
index 06c7a5e45..9a1a93148 100644
--- a/Source/WebCore/loader/icon/IconController.cpp
+++ b/Source/WebCore/loader/icon/IconController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2011, 2015 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
@@ -16,7 +16,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.
*
@@ -37,12 +37,14 @@
#include "Document.h"
#include "DocumentLoader.h"
+#include "ElementChildIterator.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
+#include "HTMLHeadElement.h"
+#include "HTMLLinkElement.h"
#include "IconDatabase.h"
-#include "IconDatabaseBase.h"
#include "IconLoader.h"
-#include "IconURL.h"
+#include "LinkIconType.h"
#include "Logging.h"
#include "MainFrame.h"
#include "Page.h"
@@ -53,7 +55,6 @@ namespace WebCore {
IconController::IconController(Frame& frame)
: m_frame(frame)
- , m_waitingForLoadDecision(false)
{
}
@@ -61,63 +62,57 @@ IconController::~IconController()
{
}
-URL IconController::url()
+static URL iconFromLinkElements(Frame& frame)
{
- IconURLs iconURLs = urlsForTypes(Favicon);
- return iconURLs.isEmpty() ? URL() : iconURLs[0].m_iconURL;
-}
-
-IconURL IconController::iconURL(IconType iconType) const
-{
- IconURL result;
- const Vector<IconURL>& iconURLs = m_frame.document()->iconURLs(iconType);
- Vector<IconURL>::const_iterator iter(iconURLs.begin());
- for (; iter != iconURLs.end(); ++iter) {
- if (result.m_iconURL.isEmpty() || !iter->m_mimeType.isEmpty())
- result = *iter;
+ // This function returns the first icon with a mime type.
+ // If no icon with mime type exists, the last icon is returned.
+ // It may make more sense to always return the last icon,
+ // but this implementation is consistent with previous behavior.
+
+ URL result;
+
+ auto* document = frame.document();
+ if (!document)
+ return result;
+
+ auto* head = document->head();
+ if (!head)
+ return result;
+
+ for (auto& linkElement : childrenOfType<HTMLLinkElement>(*head)) {
+ if (!linkElement.iconType())
+ continue;
+ if (*linkElement.iconType() != LinkIconType::Favicon)
+ continue;
+ if (linkElement.href().isEmpty())
+ continue;
+ result = linkElement.href();
+ if (!linkElement.type().isEmpty())
+ break;
}
return result;
}
-IconURLs IconController::urlsForTypes(int iconTypesMask)
+URL IconController::url()
{
- IconURLs iconURLs;
- if (m_frame.tree().parent())
- return iconURLs;
-
- if (iconTypesMask & Favicon && !appendToIconURLs(Favicon, &iconURLs))
- iconURLs.append(defaultURL(Favicon));
-
-#if ENABLE(TOUCH_ICON_LOADING)
- int missedIcons = 0;
- if (iconTypesMask & TouchPrecomposedIcon)
- missedIcons += appendToIconURLs(TouchPrecomposedIcon, &iconURLs) ? 0:1;
-
- if (iconTypesMask & TouchIcon)
- missedIcons += appendToIconURLs(TouchIcon, &iconURLs) ? 0:1;
-
- // Only return the default touch icons when the both were required and neither was gotten.
- if (missedIcons == 2) {
- iconURLs.append(defaultURL(TouchPrecomposedIcon));
- iconURLs.append(defaultURL(TouchIcon));
- }
-#endif
-
- // Finally, append all remaining icons of this type.
- const Vector<IconURL>& allIconURLs = m_frame.document()->iconURLs(iconTypesMask);
- for (Vector<IconURL>::const_iterator iter = allIconURLs.begin(); iter != allIconURLs.end(); ++iter) {
- int i;
- int iconCount = iconURLs.size();
- for (i = 0; i < iconCount; ++i) {
- if (*iter == iconURLs.at(i))
- break;
- }
- if (i == iconCount)
- iconURLs.append(*iter);
+ if (!m_frame.isMainFrame())
+ return URL();
+
+ auto icon = iconFromLinkElements(m_frame);
+ if (!icon.isEmpty())
+ return icon;
+
+ icon = m_frame.document()->completeURL(ASCIILiteral("/favicon.ico"));
+ if (icon.protocolIsInHTTPFamily()) {
+ // FIXME: Not sure we need to remove credentials like this.
+ // However this preserves behavior this code path has historically had.
+ icon.setUser(String());
+ icon.setPass(String());
+ return icon;
}
- return iconURLs;
+ return URL();
}
void IconController::commitToDatabase(const URL& icon)
@@ -142,9 +137,8 @@ void IconController::startLoader()
if (!documentCanHaveIcon(m_frame.document()->url()))
return;
- URL iconURL(url());
- String urlString(iconURL.string());
- if (urlString.isEmpty())
+ URL iconURL = url();
+ if (iconURL.isEmpty())
return;
// People who want to avoid loading images generally want to avoid loading all images, unless an exception has been made for site icons.
@@ -154,30 +148,30 @@ void IconController::startLoader()
// If we're reloading the page, always start the icon load now.
// FIXME: How can this condition ever be true?
- if (m_frame.loader().loadType() == FrameLoadTypeReload && m_frame.loader().loadType() == FrameLoadTypeReloadFromOrigin) {
+ if (m_frame.loader().loadType() == FrameLoadType::Reload && m_frame.loader().loadType() == FrameLoadType::ReloadFromOrigin) {
continueLoadWithDecision(IconLoadYes);
return;
}
if (iconDatabase().supportsAsynchronousMode()) {
// FIXME (<rdar://problem/9168605>) - We should support in-memory-only private browsing icons in asynchronous icon database mode.
- if (m_frame.page() && m_frame.page()->settings().privateBrowsingEnabled())
+ if (m_frame.page() && m_frame.page()->usesEphemeralSession())
return;
- m_frame.loader().documentLoader()->getIconLoadDecisionForIconURL(urlString);
+ m_frame.loader().documentLoader()->getIconLoadDecisionForIconURL(iconURL.string());
// Commit the icon url mapping to the database just in case we don't end up loading later.
commitToDatabase(iconURL);
return;
}
- IconLoadDecision decision = iconDatabase().synchronousLoadDecisionForIconURL(urlString, m_frame.loader().documentLoader());
+ IconLoadDecision decision = iconDatabase().synchronousLoadDecisionForIconURL(iconURL.string(), m_frame.loader().documentLoader());
if (decision == IconLoadUnknown) {
// In this case, we may end up loading the icon later, but we still want to commit the icon url mapping to the database
// just in case we don't end up loading later - if we commit the mapping a second time after the load, that's no big deal
// We also tell the client to register for the notification that the icon is received now so it isn't missed in case the
// icon is later read in from disk
- LOG(IconDatabase, "IconController %p might load icon %s later", this, urlString.ascii().data());
+ LOG(IconDatabase, "IconController %p might load icon %s later", this, iconURL.string().utf8().data());
m_waitingForLoadDecision = true;
m_frame.loader().client().registerForIconNotification();
commitToDatabase(iconURL);
@@ -208,16 +202,15 @@ void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision)
ASSERT(iconLoadDecision != IconLoadUnknown);
if (iconLoadDecision == IconLoadNo) {
- URL iconURL(url());
- String urlString(iconURL.string());
- if (urlString.isEmpty())
+ URL iconURL = url();
+ if (iconURL.isEmpty())
return;
- LOG(IconDatabase, "IconController::startLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", urlString.ascii().data());
+ LOG(IconDatabase, "IconController::startLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", iconURL.string().utf8().data());
commitToDatabase(iconURL);
if (iconDatabase().supportsAsynchronousMode()) {
- m_frame.loader().documentLoader()->getIconDataForIconURL(urlString);
+ m_frame.loader().documentLoader()->getIconDataForIconURL(iconURL.string());
return;
}
@@ -225,8 +218,8 @@ void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision)
// If the icon data hasn't been read in from disk yet, kick off the read of the icon from the database to make sure someone
// has done it. This is after registering for the notification so the WebView can call the appropriate delegate method.
// Otherwise if the icon data *is* available, notify the delegate
- if (!iconDatabase().synchronousIconDataKnownForIconURL(urlString)) {
- LOG(IconDatabase, "Told not to load icon %s but icon data is not yet available - registering for notification and requesting load from disk", urlString.ascii().data());
+ if (!iconDatabase().synchronousIconDataKnownForIconURL(iconURL.string())) {
+ LOG(IconDatabase, "Told not to load icon %s but icon data is not yet available - registering for notification and requesting load from disk", iconURL.string().ascii().data());
m_frame.loader().client().registerForIconNotification();
iconDatabase().synchronousIconForPageURL(m_frame.document()->url().string(), IntSize(0, 0));
iconDatabase().synchronousIconForPageURL(m_frame.loader().initialRequest().url().string(), IntSize(0, 0));
@@ -242,45 +235,4 @@ void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision)
m_iconLoader->startLoading();
}
-bool IconController::appendToIconURLs(IconType iconType, IconURLs* iconURLs)
-{
- IconURL faviconURL = iconURL(iconType);
- if (faviconURL.m_iconURL.isEmpty())
- return false;
-
- iconURLs->append(faviconURL);
- return true;
-}
-
-IconURL IconController::defaultURL(IconType iconType)
-{
- // Don't return a favicon iconURL unless we're http or https
- URL documentURL = m_frame.document()->url();
- if (!documentURL.protocolIsInHTTPFamily())
- return IconURL();
-
- URL url;
- bool couldSetProtocol = url.setProtocol(documentURL.protocol());
- ASSERT_UNUSED(couldSetProtocol, couldSetProtocol);
- url.setHost(documentURL.host());
- if (documentURL.hasPort())
- url.setPort(documentURL.port());
-
- if (iconType == Favicon) {
- url.setPath("/favicon.ico");
- return IconURL::defaultIconURL(url, Favicon);
- }
-#if ENABLE(TOUCH_ICON_LOADING)
- if (iconType == TouchPrecomposedIcon) {
- url.setPath("/apple-touch-icon-precomposed.png");
- return IconURL::defaultIconURL(url, TouchPrecomposedIcon);
- }
- if (iconType == TouchIcon) {
- url.setPath("/apple-touch-icon.png");
- return IconURL::defaultIconURL(url, TouchIcon);
- }
-#endif
- return IconURL();
-}
-
}
diff --git a/Source/WebCore/loader/icon/IconController.h b/Source/WebCore/loader/icon/IconController.h
index 83844b9d4..31b1562a1 100644
--- a/Source/WebCore/loader/icon/IconController.h
+++ b/Source/WebCore/loader/icon/IconController.h
@@ -12,7 +12,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.
*
@@ -28,28 +28,23 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IconController_h
-#define IconController_h
+#pragma once
#include "IconDatabaseBase.h"
-#include "IconURL.h"
-#include "URL.h"
namespace WebCore {
class Frame;
class IconLoader;
+class URL;
class IconController {
- WTF_MAKE_NONCOPYABLE(IconController);
WTF_MAKE_FAST_ALLOCATED;
public:
explicit IconController(Frame&);
~IconController();
- URL url();
- IconURLs urlsForTypes(int iconTypesMask);
- IconURL iconURL(IconType) const;
+ WEBCORE_EXPORT URL url();
void startLoader();
void stopLoader();
@@ -60,15 +55,9 @@ public:
void commitToDatabase(const URL& icon);
private:
- bool appendToIconURLs(IconType, IconURLs*);
- IconURL defaultURL(IconType);
-
Frame& m_frame;
-
std::unique_ptr<IconLoader> m_iconLoader;
- bool m_waitingForLoadDecision;
+ bool m_waitingForLoadDecision { false };
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/loader/icon/IconDatabase.cpp b/Source/WebCore/loader/icon/IconDatabase.cpp
index 39272e4d6..4cdcfaad6 100644
--- a/Source/WebCore/loader/icon/IconDatabase.cpp
+++ b/Source/WebCore/loader/icon/IconDatabase.cpp
@@ -11,10 +11,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -34,16 +34,14 @@
#include "IconDatabaseClient.h"
#include "IconRecord.h"
#include "Image.h"
-#include "IntSize.h"
#include "Logging.h"
#include "SQLiteStatement.h"
#include "SQLiteTransaction.h"
#include "SuddenTermination.h"
#include <wtf/AutodrainedPool.h>
-#include <wtf/CurrentTime.h>
#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/text/CString.h>
// For methods that are meant to support API from the main thread - should not be called internally
#define ASSERT_NOT_SYNC_THREAD() ASSERT(!m_syncThreadRunning || !IS_ICON_SYNC_THREAD())
@@ -82,7 +80,7 @@ static const int notUsedIconExpirationTime = 60*60*24*30;
#if !LOG_DISABLED || !ERROR_DISABLED
static String urlForLogging(const String& url)
{
- static unsigned urlTruncationLength = 120;
+ static const unsigned urlTruncationLength = 120;
if (url.length() < urlTruncationLength)
return url;
@@ -90,19 +88,19 @@ static String urlForLogging(const String& url)
}
#endif
-class DefaultIconDatabaseClient : public IconDatabaseClient {
+class DefaultIconDatabaseClient final : public IconDatabaseClient {
WTF_MAKE_FAST_ALLOCATED;
public:
- virtual void didImportIconURLForPageURL(const String&) { }
- virtual void didImportIconDataForPageURL(const String&) { }
- virtual void didChangeIconForPageURL(const String&) { }
- virtual void didRemoveAllIcons() { }
- virtual void didFinishURLImport() { }
+ void didImportIconURLForPageURL(const String&) override { }
+ void didImportIconDataForPageURL(const String&) override { }
+ void didChangeIconForPageURL(const String&) override { }
+ void didRemoveAllIcons() override { }
+ void didFinishURLImport() override { }
};
static IconDatabaseClient* defaultClient()
{
- static IconDatabaseClient* defaultClient = new DefaultIconDatabaseClient();
+ static IconDatabaseClient* defaultClient = new DefaultIconDatabaseClient;
return defaultClient;
}
@@ -171,7 +169,11 @@ void IconDatabase::close()
m_removeIconsRequested = false;
m_syncDB.close();
- ASSERT(!isOpen());
+
+ // If there are still main thread callbacks in flight then the database might not actually be closed yet.
+ // But if it is closed, notify the client now.
+ if (!isOpen() && m_client)
+ m_client->didClose();
}
void IconDatabase::removeAllIcons()
@@ -185,28 +187,26 @@ void IconDatabase::removeAllIcons()
// Clear the in-memory record of every IconRecord, anything waiting to be read from disk, and anything waiting to be written to disk
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
// Clear the IconRecords for every page URL - RefCounting will cause the IconRecords themselves to be deleted
// We don't delete the actual PageRecords because we have the "retain icon for url" count to keep track of
- HashMap<String, PageURLRecord*>::iterator iter = m_pageURLToRecordMap.begin();
- HashMap<String, PageURLRecord*>::iterator end = m_pageURLToRecordMap.end();
- for (; iter != end; ++iter)
- (*iter).value->setIconRecord(0);
-
+ for (auto& pageURL : m_pageURLToRecordMap.values())
+ pageURL->setIconRecord(nullptr);
+
// Clear the iconURL -> IconRecord map
m_iconURLToRecordMap.clear();
// Clear all in-memory records of things that need to be synced out to disk
{
- MutexLocker locker(m_pendingSyncLock);
+ LockHolder locker(m_pendingSyncLock);
m_pageURLsPendingSync.clear();
m_iconsPendingSync.clear();
}
// Clear all in-memory records of things that need to be read in from disk
{
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
m_pageURLsPendingImport.clear();
m_pageURLsInterestedInIcons.clear();
m_iconsPendingReading.clear();
@@ -226,9 +226,9 @@ Image* IconDatabase::synchronousIconForPageURL(const String& pageURLOriginal, co
// We should go our of our way to only copy it if we have to store it
if (!isOpen() || !documentCanHaveIcon(pageURLOriginal))
- return 0;
+ return nullptr;
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
performPendingRetainAndReleaseOperations();
@@ -244,14 +244,14 @@ Image* IconDatabase::synchronousIconForPageURL(const String& pageURLOriginal, co
// 1 - The initial url import is incomplete and this pageURL was marked to be notified once it is complete if an iconURL exists
// 2 - The initial url import IS complete and this pageURL has no icon
if (!pageRecord) {
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
// Import is ongoing, there might be an icon. In this case, register to be notified when the icon comes in
// If we ever reach this condition, we know we've already made the pageURL copy
if (!m_iconURLImportComplete)
m_pageURLsInterestedInIcons.add(pageURLCopy);
- return 0;
+ return nullptr;
}
IconRecord* iconRecord = pageRecord->iconRecord();
@@ -260,14 +260,14 @@ Image* IconDatabase::synchronousIconForPageURL(const String& pageURLOriginal, co
// In this case, the pageURL is already in the set to alert the client when the iconURL mapping is complete so
// we can just bail now
if (!m_iconURLImportComplete && !iconRecord)
- return 0;
+ return nullptr;
// Assuming we're done initializing and cleanup is allowed,
// the only way we should *not* have an icon record is if this pageURL is retained but has no icon yet.
ASSERT(iconRecord || databaseCleanupCounter || m_retainedPageURLs.contains(pageURLOriginal));
if (!iconRecord)
- return 0;
+ return nullptr;
// If it's a new IconRecord object that doesn't have its imageData set yet,
// mark it to be read by the background thread
@@ -275,17 +275,17 @@ Image* IconDatabase::synchronousIconForPageURL(const String& pageURLOriginal, co
if (pageURLCopy.isNull())
pageURLCopy = pageURLOriginal.isolatedCopy();
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
m_pageURLsInterestedInIcons.add(pageURLCopy);
m_iconsPendingReading.add(iconRecord);
wakeSyncThread();
- return 0;
+ return nullptr;
}
// If the size parameter was (0, 0) that means the caller of this method just wanted the read from disk to be kicked off
// and isn't actually interested in the image return value
if (size == IntSize(0, 0))
- return 0;
+ return nullptr;
// PARANOID DISCUSSION: This method makes some assumptions. It returns a WebCore::image which the icon database might dispose of at anytime in the future,
// and Images aren't ref counted. So there is no way for the client to guarantee continued existence of the image.
@@ -300,13 +300,13 @@ Image* IconDatabase::synchronousIconForPageURL(const String& pageURLOriginal, co
return iconRecord->image(size);
}
-PassNativeImagePtr IconDatabase::synchronousNativeIconForPageURL(const String& pageURLOriginal, const IntSize& size)
+NativeImagePtr IconDatabase::synchronousNativeIconForPageURL(const String& pageURLOriginal, const IntSize& size)
{
Image* icon = synchronousIconForPageURL(pageURLOriginal, size);
if (!icon)
- return 0;
+ return nullptr;
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
return icon->nativeImageForCurrentFrame();
}
@@ -328,7 +328,7 @@ String IconDatabase::synchronousIconURLForPageURL(const String& pageURLOriginal)
if (!isOpen() || !documentCanHaveIcon(pageURLOriginal))
return String();
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
if (!pageRecord)
@@ -390,8 +390,8 @@ static inline void loadDefaultIconRecord(IconRecord* defaultIconRecord)
0x00, 0x00, 0x01, 0x52, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0A,
0xFC, 0x80, 0x00, 0x00, 0x27, 0x10, 0x00, 0x0A, 0xFC, 0x80, 0x00, 0x00, 0x27, 0x10 };
- static SharedBuffer* defaultIconBuffer = SharedBuffer::create(defaultIconData, sizeof(defaultIconData)).leakRef();
- defaultIconRecord->setImageData(defaultIconBuffer);
+ static auto& defaultIconBuffer = SharedBuffer::create(defaultIconData, sizeof(defaultIconData)).leakRef();
+ defaultIconRecord->setImageData(&defaultIconBuffer);
}
#endif
@@ -416,7 +416,7 @@ void IconDatabase::retainIconForPageURL(const String& pageURL)
return;
{
- MutexLocker locker(m_urlsToRetainOrReleaseLock);
+ LockHolder locker(m_urlsToRetainOrReleaseLock);
m_urlsToRetain.add(pageURL.isolatedCopy());
m_retainOrReleaseIconRequested = true;
}
@@ -449,7 +449,7 @@ void IconDatabase::performRetainIconForPageURL(const String& pageURLOriginal, in
if (!m_iconURLImportComplete)
return;
- MutexLocker locker(m_pendingSyncLock);
+ LockHolder locker(m_pendingSyncLock);
// If this pageURL waiting to be sync'ed, update the sync record
// This saves us in the case where a page was ready to be deleted from the database but was just retained - so theres no need to delete it!
if (!m_privateBrowsingEnabled && m_pageURLsPendingSync.contains(pageURL)) {
@@ -469,7 +469,7 @@ void IconDatabase::releaseIconForPageURL(const String& pageURL)
return;
{
- MutexLocker locker(m_urlsToRetainOrReleaseLock);
+ LockHolder locker(m_urlsToRetainOrReleaseLock);
m_urlsToRelease.add(pageURL.isolatedCopy());
m_retainOrReleaseIconRequested = true;
}
@@ -505,7 +505,7 @@ void IconDatabase::performReleaseIconForPageURL(const String& pageURLOriginal, i
ASSERT(!iconRecord || (iconRecord && m_iconURLToRecordMap.get(iconRecord->iconURL()) == iconRecord));
{
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
// Since this pageURL is going away, there's no reason anyone would ever be interested in its read results
if (!m_iconURLImportComplete)
@@ -521,7 +521,7 @@ void IconDatabase::performReleaseIconForPageURL(const String& pageURLOriginal, i
// Mark stuff for deletion from the database only if we're not in private browsing
if (!m_privateBrowsingEnabled) {
- MutexLocker locker(m_pendingSyncLock);
+ LockHolder locker(m_pendingSyncLock);
m_pageURLsPendingSync.set(pageURLOriginal.isolatedCopy(), pageRecord->snapshot(true));
// If this page is the last page to refer to a particular IconRecord, that IconRecord needs to
@@ -533,7 +533,7 @@ void IconDatabase::performReleaseIconForPageURL(const String& pageURLOriginal, i
delete pageRecord;
}
-void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> dataOriginal, const String& iconURLOriginal)
+void IconDatabase::setIconDataForIconURL(SharedBuffer* dataOriginal, const String& iconURLOriginal)
{
ASSERT_NOT_SYNC_THREAD();
@@ -542,23 +542,23 @@ void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> dataOriginal,
if (!isOpen() || iconURLOriginal.isEmpty())
return;
- RefPtr<SharedBuffer> data = dataOriginal ? dataOriginal->copy() : PassRefPtr<SharedBuffer>(0);
+ auto data = dataOriginal ? RefPtr<SharedBuffer> { dataOriginal->copy() } : nullptr;
String iconURL = iconURLOriginal.isolatedCopy();
Vector<String> pageURLs;
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
// If this icon was pending a read, remove it from that set because this new data should override what is on disk
RefPtr<IconRecord> icon = m_iconURLToRecordMap.get(iconURL);
if (icon) {
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
m_iconsPendingReading.remove(icon.get());
} else
icon = getOrCreateIconRecord(iconURL);
// Update the data and set the time stamp
- icon->setImageData(data.release());
+ icon->setImageData(WTFMove(data));
icon->setTimestamp((int)currentTime());
// Copy the current retaining pageURLs - if any - to notify them of the change
@@ -566,7 +566,7 @@ void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> dataOriginal,
// Mark the IconRecord as requiring an update to the database only if private browsing is disabled
if (!m_privateBrowsingEnabled) {
- MutexLocker locker(m_pendingSyncLock);
+ LockHolder locker(m_pendingSyncLock);
m_iconsPendingSync.set(iconURL, icon->snapshot());
}
@@ -584,11 +584,11 @@ void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> dataOriginal,
// Start the timer to commit this change - or further delay the timer if it was already started
scheduleOrDeferSyncTimer();
- for (unsigned i = 0; i < pageURLs.size(); ++i) {
+ for (auto& pageURL : pageURLs) {
AutodrainedPool pool;
- LOG(IconDatabase, "Dispatching notification that retaining pageURL %s has a new icon", urlForLogging(pageURLs[i]).ascii().data());
- m_client->didChangeIconForPageURL(pageURLs[i]);
+ LOG(IconDatabase, "Dispatching notification that retaining pageURL %s has a new icon", urlForLogging(pageURL).ascii().data());
+ m_client->didChangeIconForPageURL(pageURL);
}
}
}
@@ -607,7 +607,7 @@ void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const Str
String iconURL, pageURL;
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
@@ -635,13 +635,13 @@ void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const Str
ASSERT(iconRecord->retainingPageURLs().size() == 0);
LOG(IconDatabase, "Icon for icon url %s is about to be destroyed - removing mapping for it", urlForLogging(iconRecord->iconURL()).ascii().data());
m_iconURLToRecordMap.remove(iconRecord->iconURL());
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
m_iconsPendingReading.remove(iconRecord.get());
}
// And mark this mapping to be added to the database
if (!m_privateBrowsingEnabled) {
- MutexLocker locker(m_pendingSyncLock);
+ LockHolder locker(m_pendingSyncLock);
m_pageURLsPendingSync.set(pageURL, pageRecord->snapshot());
// If the icon is on its last ref, mark it for deletion
@@ -673,7 +673,7 @@ IconLoadDecision IconDatabase::synchronousLoadDecisionForIconURL(const String& i
// 1 - When we read the icon urls from disk, getting the timeStamp at the same time
// 2 - When we get a new icon from the loader, in which case the timestamp is set at that time
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL)) {
LOG(IconDatabase, "Found expiration time on a present icon based on existing IconRecord");
return static_cast<int>(currentTime()) - static_cast<int>(icon->getTimestamp()) > iconExpirationTime ? IconLoadYes : IconLoadNo;
@@ -681,7 +681,7 @@ IconLoadDecision IconDatabase::synchronousLoadDecisionForIconURL(const String& i
}
// If we don't have a record for it, but we *have* imported all iconURLs from disk, then we should load it now
- MutexLocker readingLocker(m_pendingReadingLock);
+ LockHolder readingLocker(m_pendingReadingLock);
if (m_iconURLImportComplete)
return IconLoadYes;
@@ -698,7 +698,7 @@ bool IconDatabase::synchronousIconDataKnownForIconURL(const String& iconURL)
{
ASSERT_NOT_SYNC_THREAD();
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL))
return icon->imageDataStatus() != ImageDataStatusUnknown;
@@ -753,39 +753,36 @@ void IconDatabase::checkIntegrityBeforeOpening()
size_t IconDatabase::pageURLMappingCount()
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
return m_pageURLToRecordMap.size();
}
size_t IconDatabase::retainedPageURLCount()
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
performPendingRetainAndReleaseOperations();
return m_retainedPageURLs.size();
}
size_t IconDatabase::iconRecordCount()
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
return m_iconURLToRecordMap.size();
}
size_t IconDatabase::iconRecordCountWithData()
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
size_t result = 0;
-
- HashMap<String, IconRecord*>::iterator i = m_iconURLToRecordMap.begin();
- HashMap<String, IconRecord*>::iterator end = m_iconURLToRecordMap.end();
-
- for (; i != end; ++i)
- result += ((*i).value->imageDataStatus() == ImageDataStatusPresent);
-
+
+ for (auto& iconRecord : m_iconURLToRecordMap.values())
+ result += (iconRecord->imageDataStatus() == ImageDataStatusPresent);
+
return result;
}
IconDatabase::IconDatabase()
- : m_syncTimer(this, &IconDatabase::syncTimerFired)
+ : m_syncTimer(*this, &IconDatabase::syncTimerFired)
, m_syncThreadRunning(false)
, m_scheduleOrDeferSyncTimerRequested(false)
, m_isEnabled(false)
@@ -796,6 +793,7 @@ IconDatabase::IconDatabase()
, m_syncThreadHasWorkToDo(false)
, m_retainOrReleaseIconRequested(false)
, m_initialPruningComplete(false)
+ , m_mainThreadCallbackCount(0)
, m_client(defaultClient())
{
LOG(IconDatabase, "Creating IconDatabase %p", this);
@@ -807,11 +805,6 @@ IconDatabase::~IconDatabase()
ASSERT(!isOpen());
}
-void IconDatabase::notifyPendingLoadDecisionsOnMainThread(void* context)
-{
- static_cast<IconDatabase*>(context)->notifyPendingLoadDecisions();
-}
-
void IconDatabase::notifyPendingLoadDecisions()
{
ASSERT_NOT_SYNC_THREAD();
@@ -819,37 +812,24 @@ void IconDatabase::notifyPendingLoadDecisions()
// This method should only be called upon completion of the initial url import from the database
ASSERT(m_iconURLImportComplete);
LOG(IconDatabase, "Notifying all DocumentLoaders that were waiting on a load decision for their icons");
-
- HashSet<RefPtr<DocumentLoader>>::iterator i = m_loadersPendingDecision.begin();
- HashSet<RefPtr<DocumentLoader>>::iterator end = m_loadersPendingDecision.end();
-
- for (; i != end; ++i)
- if ((*i)->refCount() > 1)
- (*i)->iconLoadDecisionAvailable();
-
+
+ for (auto& loader : m_loadersPendingDecision) {
+ if (loader->refCount() > 1)
+ loader->iconLoadDecisionAvailable();
+ }
+
m_loadersPendingDecision.clear();
}
void IconDatabase::wakeSyncThread()
{
- MutexLocker locker(m_syncLock);
+ LockHolder locker(m_syncLock);
if (!m_disableSuddenTerminationWhileSyncThreadHasWorkToDo)
m_disableSuddenTerminationWhileSyncThreadHasWorkToDo = std::make_unique<SuddenTerminationDisabler>();
m_syncThreadHasWorkToDo = true;
- m_syncCondition.signal();
-}
-
-void IconDatabase::performScheduleOrDeferSyncTimer()
-{
- m_syncTimer.startOneShot(updateTimerDelay);
- m_scheduleOrDeferSyncTimerRequested = false;
-}
-
-void IconDatabase::performScheduleOrDeferSyncTimerOnMainThread(void* context)
-{
- static_cast<IconDatabase*>(context)->performScheduleOrDeferSyncTimer();
+ m_syncCondition.notifyOne();
}
void IconDatabase::scheduleOrDeferSyncTimer()
@@ -863,10 +843,13 @@ void IconDatabase::scheduleOrDeferSyncTimer()
m_disableSuddenTerminationWhileSyncTimerScheduled = std::make_unique<SuddenTerminationDisabler>();
m_scheduleOrDeferSyncTimerRequested = true;
- callOnMainThread(performScheduleOrDeferSyncTimerOnMainThread, this);
+ callOnMainThread([this] {
+ m_syncTimer.startOneShot(updateTimerDelay);
+ m_scheduleOrDeferSyncTimerRequested = false;
+ });
}
-void IconDatabase::syncTimerFired(Timer<IconDatabase>&)
+void IconDatabase::syncTimerFired()
{
ASSERT_NOT_SYNC_THREAD();
wakeSyncThread();
@@ -880,35 +863,39 @@ void IconDatabase::syncTimerFired(Timer<IconDatabase>&)
bool IconDatabase::isOpen() const
{
- MutexLocker locker(m_syncLock);
- return m_syncDB.isOpen();
+ return isOpenBesidesMainThreadCallbacks() || m_mainThreadCallbackCount;
+}
+
+bool IconDatabase::isOpenBesidesMainThreadCallbacks() const
+{
+ LockHolder locker(m_syncLock);
+ return m_syncThreadRunning || m_syncDB.isOpen();
}
String IconDatabase::databasePath() const
{
- MutexLocker locker(m_syncLock);
+ LockHolder locker(m_syncLock);
return m_completeDatabasePath.isolatedCopy();
}
String IconDatabase::defaultDatabaseFilename()
{
- DEFINE_STATIC_LOCAL(String, defaultDatabaseFilename, (ASCIILiteral("WebpageIcons.db")));
- return defaultDatabaseFilename.isolatedCopy();
+ static NeverDestroyed<String> defaultDatabaseFilename(ASCIILiteral("WebpageIcons.db"));
+ return defaultDatabaseFilename.get().isolatedCopy();
}
// Unlike getOrCreatePageURLRecord(), getOrCreateIconRecord() does not mark the icon as "interested in import"
-PassRefPtr<IconRecord> IconDatabase::getOrCreateIconRecord(const String& iconURL)
+Ref<IconRecord> IconDatabase::getOrCreateIconRecord(const String& iconURL)
{
// Clients of getOrCreateIconRecord() are required to acquire the m_urlAndIconLock before calling this method
ASSERT(!m_urlAndIconLock.tryLock());
- if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL))
- return icon;
+ if (auto* icon = m_iconURLToRecordMap.get(iconURL))
+ return *icon;
- RefPtr<IconRecord> newIcon = IconRecord::create(iconURL);
- m_iconURLToRecordMap.set(iconURL, newIcon.get());
-
- return newIcon.release();
+ auto newIcon = IconRecord::create(iconURL);
+ m_iconURLToRecordMap.set(iconURL, newIcon.ptr());
+ return newIcon;
}
// This method retrieves the existing PageURLRecord, or creates a new one and marks it as "interested in the import" for later notification
@@ -918,11 +905,11 @@ PageURLRecord* IconDatabase::getOrCreatePageURLRecord(const String& pageURL)
ASSERT(!m_urlAndIconLock.tryLock());
if (!documentCanHaveIcon(pageURL))
- return 0;
+ return nullptr;
PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL);
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
if (!m_iconURLImportComplete) {
// If the initial import of all URLs hasn't completed and we have no page record, we assume we *might* know about this later and create a record for it
if (!pageRecord) {
@@ -935,7 +922,7 @@ PageURLRecord* IconDatabase::getOrCreatePageURLRecord(const String& pageURL)
// Mark the URL as "interested in the result of the import" then bail
if (!pageRecord->iconRecord()) {
m_pageURLsPendingImport.add(pageURL);
- return 0;
+ return nullptr;
}
}
@@ -991,7 +978,7 @@ void IconDatabase::iconDatabaseSyncThread()
}
{
- MutexLocker locker(m_syncLock);
+ LockHolder locker(m_syncLock);
if (!m_syncDB.open(m_completeDatabasePath)) {
LOG_ERROR("Unable to open icon database at path %s - %s", m_completeDatabasePath.ascii().data(), m_syncDB.lastErrorMsg());
return;
@@ -1119,7 +1106,7 @@ void IconDatabase::performOpenInitialization()
m_syncDB.close();
{
- MutexLocker locker(m_syncLock);
+ LockHolder locker(m_syncLock);
// Should've been consumed by SQLite, delete just to make sure we don't see it again in the future;
deleteFile(m_completeDatabasePath + "-journal");
deleteFile(m_completeDatabasePath);
@@ -1165,16 +1152,16 @@ bool IconDatabase::checkIntegrity()
ASSERT_ICON_SYNC_THREAD();
SQLiteStatement integrity(m_syncDB, "PRAGMA integrity_check;");
- if (integrity.prepare() != SQLResultOk) {
+ if (integrity.prepare() != SQLITE_OK) {
LOG_ERROR("checkIntegrity failed to execute");
return false;
}
int resultCode = integrity.step();
- if (resultCode == SQLResultOk)
+ if (resultCode == SQLITE_OK)
return true;
-
- if (resultCode != SQLResultRow)
+
+ if (resultCode != SQLITE_ROW)
return false;
int columns = integrity.columnCount();
@@ -1209,25 +1196,25 @@ void IconDatabase::performURLImport()
SQLiteStatement query(m_syncDB, importQuery);
- if (query.prepare() != SQLResultOk) {
+ if (query.prepare() != SQLITE_OK) {
LOG_ERROR("Unable to prepare icon url import query");
return;
}
int result = query.step();
- while (result == SQLResultRow) {
+ while (result == SQLITE_ROW) {
AutodrainedPool pool;
String pageURL = query.getColumnText(0);
String iconURL = query.getColumnText(1);
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL);
// If the pageRecord doesn't exist in this map, then no one has retained this pageURL
// If the s_databaseCleanupCounter count is non-zero, then we're not supposed to be pruning the database in any manner,
- // so go ahead and actually create a pageURLRecord for this url even though it's not retained.
+ // so actually create a pageURLRecord for this url even though it's not retained.
// If database cleanup *is* allowed, we don't want to bother pulling in a page url from disk that noone is actually interested
// in - we'll prune it later instead!
if (!pageRecord && databaseCleanupCounter && documentCanHaveIcon(pageURL)) {
@@ -1254,7 +1241,7 @@ void IconDatabase::performURLImport()
// one for the URL and one for the Image itself
// Note that WebIconDatabase is not neccessarily API so we might be able to make this change
{
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
if (m_pageURLsPendingImport.contains(pageURL)) {
dispatchDidImportIconURLForPageURLOnMainThread(pageURL);
m_pageURLsPendingImport.remove(pageURL);
@@ -1270,14 +1257,14 @@ void IconDatabase::performURLImport()
result = query.step();
}
- if (result != SQLResultDone)
+ if (result != SQLITE_DONE)
LOG(IconDatabase, "Error reading page->icon url mappings from database");
// Clear the m_pageURLsPendingImport set - either the page URLs ended up with an iconURL (that we'll notify about) or not,
// but after m_iconURLImportComplete is set to true, we don't care about this set anymore
Vector<String> urls;
{
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
urls.appendRange(m_pageURLsPendingImport.begin(), m_pageURLsPendingImport.end());
m_pageURLsPendingImport.clear();
@@ -1290,15 +1277,15 @@ void IconDatabase::performURLImport()
// Remove unretained ones if database cleanup is allowed
// Keep a set of ones that are retained and pending notification
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
performPendingRetainAndReleaseOperations();
- for (unsigned i = 0; i < urls.size(); ++i) {
- if (!m_retainedPageURLs.contains(urls[i])) {
- PageURLRecord* record = m_pageURLToRecordMap.get(urls[i]);
+ for (auto& url : urls) {
+ if (!m_retainedPageURLs.contains(url)) {
+ PageURLRecord* record = m_pageURLToRecordMap.get(url);
if (record && !databaseCleanupCounter) {
- m_pageURLToRecordMap.remove(urls[i]);
+ m_pageURLToRecordMap.remove(url);
IconRecord* iconRecord = record->iconRecord();
// If this page is the only remaining retainer of its icon, mark that icon for deletion and don't bother
@@ -1307,12 +1294,12 @@ void IconDatabase::performURLImport()
m_iconURLToRecordMap.remove(iconRecord->iconURL());
{
- MutexLocker locker(m_pendingReadingLock);
- m_pageURLsInterestedInIcons.remove(urls[i]);
+ LockHolder locker(m_pendingReadingLock);
+ m_pageURLsInterestedInIcons.remove(url);
m_iconsPendingReading.remove(iconRecord);
}
{
- MutexLocker locker(m_pendingSyncLock);
+ LockHolder locker(m_pendingSyncLock);
m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapshot(true));
}
}
@@ -1320,18 +1307,18 @@ void IconDatabase::performURLImport()
delete record;
}
} else {
- urlsToNotify.append(urls[i]);
+ urlsToNotify.append(url);
}
}
}
LOG(IconDatabase, "Notifying %lu interested page URLs that their icon URL is known due to the import", static_cast<unsigned long>(urlsToNotify.size()));
// Now that we don't hold any locks, perform the actual notifications
- for (unsigned i = 0; i < urlsToNotify.size(); ++i) {
+ for (auto& url : urlsToNotify) {
AutodrainedPool pool;
- LOG(IconDatabase, "Notifying icon info known for pageURL %s", urlsToNotify[i].ascii().data());
- dispatchDidImportIconURLForPageURLOnMainThread(urlsToNotify[i]);
+ LOG(IconDatabase, "Notifying icon info known for pageURL %s", url.ascii().data());
+ dispatchDidImportIconURLForPageURLOnMainThread(url);
if (shouldStopThreadActivity())
return;
}
@@ -1340,7 +1327,9 @@ void IconDatabase::performURLImport()
dispatchDidFinishURLImportOnMainThread();
// Notify all DocumentLoaders that were waiting for an icon load decision on the main thread
- callOnMainThread(notifyPendingLoadDecisionsOnMainThread, this);
+ callOnMainThread([this] {
+ notifyPendingLoadDecisions();
+ });
}
void IconDatabase::syncThreadMainLoop()
@@ -1349,7 +1338,7 @@ void IconDatabase::syncThreadMainLoop()
m_syncLock.lock();
- std::unique_ptr<SuddenTerminationDisabler> disableSuddenTermination = std::move(m_disableSuddenTerminationWhileSyncThreadHasWorkToDo);
+ std::unique_ptr<SuddenTerminationDisabler> disableSuddenTermination = WTFMove(m_disableSuddenTerminationWhileSyncThreadHasWorkToDo);
// We'll either do any pending work on our first pass through the loop, or we'll terminate
// without doing any work. Either way we're dealing with any currently-pending work.
@@ -1371,11 +1360,13 @@ void IconDatabase::syncThreadMainLoop()
}
// Then, if the thread should be quitting, quit now!
- if (m_threadTerminationRequested)
- break;
+ if (m_threadTerminationRequested) {
+ cleanupSyncThread();
+ return;
+ }
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
performPendingRetainAndReleaseOperations();
}
@@ -1437,7 +1428,7 @@ void IconDatabase::syncThreadMainLoop()
m_syncThreadHasWorkToDo = false;
ASSERT(m_disableSuddenTerminationWhileSyncThreadHasWorkToDo);
- disableSuddenTermination = std::move(m_disableSuddenTerminationWhileSyncThreadHasWorkToDo);
+ disableSuddenTermination = WTFMove(m_disableSuddenTerminationWhileSyncThreadHasWorkToDo);
}
m_syncLock.unlock();
@@ -1455,7 +1446,7 @@ void IconDatabase::performPendingRetainAndReleaseOperations()
HashCountedSet<String> toRelease;
{
- MutexLocker pendingWorkLocker(m_urlsToRetainOrReleaseLock);
+ LockHolder pendingWorkLocker(m_urlsToRetainOrReleaseLock);
if (!m_retainOrReleaseIconRequested)
return;
@@ -1467,14 +1458,14 @@ void IconDatabase::performPendingRetainAndReleaseOperations()
m_retainOrReleaseIconRequested = false;
}
- for (HashCountedSet<String>::const_iterator it = toRetain.begin(), end = toRetain.end(); it != end; ++it) {
- ASSERT(!it->key.impl() || it->key.impl()->hasOneRef());
- performRetainIconForPageURL(it->key, it->value);
+ for (auto& entry : toRetain) {
+ ASSERT(!entry.key.impl() || entry.key.impl()->hasOneRef());
+ performRetainIconForPageURL(entry.key, entry.value);
}
- for (HashCountedSet<String>::const_iterator it = toRelease.begin(), end = toRelease.end(); it != end; ++it) {
- ASSERT(!it->key.impl() || it->key.impl()->hasOneRef());
- performReleaseIconForPageURL(it->key, it->value);
+ for (auto& entry : toRelease) {
+ ASSERT(!entry.key.impl() || entry.key.impl()->hasOneRef());
+ performReleaseIconForPageURL(entry.key, entry.value);
}
}
@@ -1492,7 +1483,7 @@ bool IconDatabase::readFromDatabase()
// This way we won't hold the lock for a long period of time
Vector<IconRecord*> icons;
{
- MutexLocker locker(m_pendingReadingLock);
+ LockHolder locker(m_pendingReadingLock);
icons.appendRange(m_iconsPendingReading.begin(), m_iconsPendingReading.end());
}
@@ -1501,17 +1492,17 @@ bool IconDatabase::readFromDatabase()
for (unsigned i = 0; i < icons.size(); ++i) {
didAnyWork = true;
- RefPtr<SharedBuffer> imageData = getImageDataForIconURLFromSQLDatabase(icons[i]->iconURL());
+ auto imageData = getImageDataForIconURLFromSQLDatabase(icons[i]->iconURL());
// Verify this icon still wants to be read from disk
{
- MutexLocker urlLocker(m_urlAndIconLock);
+ LockHolder urlLocker(m_urlAndIconLock);
{
- MutexLocker readLocker(m_pendingReadingLock);
+ LockHolder readLocker(m_pendingReadingLock);
if (m_iconsPendingReading.contains(icons[i])) {
// Set the new data
- icons[i]->setImageData(imageData.release());
+ icons[i]->setImageData(WTFMove(imageData));
// Remove this icon from the set that needs to be read
m_iconsPendingReading.remove(icons[i]);
@@ -1530,12 +1521,10 @@ bool IconDatabase::readFromDatabase()
outerHash = &(icons[i]->retainingPageURLs());
}
- HashSet<String>::const_iterator iter = outerHash->begin();
- HashSet<String>::const_iterator end = outerHash->end();
- for (; iter != end; ++iter) {
- if (innerHash->contains(*iter)) {
- LOG(IconDatabase, "%s is interested in the icon we just read. Adding it to the notification list and removing it from the interested set", urlForLogging(*iter).ascii().data());
- urlsToNotify.add(*iter);
+ for (auto& outer : *outerHash) {
+ if (innerHash->contains(outer)) {
+ LOG(IconDatabase, "%s is interested in the icon we just read. Adding it to the notification list and removing it from the interested set", urlForLogging(outer).ascii().data());
+ urlsToNotify.add(outer);
}
// If we ever get to the point were we've seen every url interested in this icon, break early
@@ -1547,10 +1536,8 @@ bool IconDatabase::readFromDatabase()
if (urlsToNotify.size() == m_pageURLsInterestedInIcons.size())
m_pageURLsInterestedInIcons.clear();
else {
- iter = urlsToNotify.begin();
- end = urlsToNotify.end();
- for (; iter != end; ++iter)
- m_pageURLsInterestedInIcons.remove(*iter);
+ for (auto& url : urlsToNotify)
+ m_pageURLsInterestedInIcons.remove(url);
}
}
}
@@ -1595,11 +1582,11 @@ bool IconDatabase::writeToDatabase()
// we'll pick it up on the next pass. This greatly simplifies the locking strategy for this method and remains cohesive with changes
// asked for by the database on the main thread
{
- MutexLocker locker(m_urlAndIconLock);
+ LockHolder locker(m_urlAndIconLock);
Vector<IconSnapshot> iconSnapshots;
Vector<PageURLSnapshot> pageSnapshots;
{
- MutexLocker locker(m_pendingSyncLock);
+ LockHolder locker(m_pendingSyncLock);
iconSnapshots.appendRange(m_iconsPendingSync.begin().values(), m_iconsPendingSync.end().values());
m_iconsPendingSync.clear();
@@ -1614,19 +1601,19 @@ bool IconDatabase::writeToDatabase()
SQLiteTransaction syncTransaction(m_syncDB);
syncTransaction.begin();
- for (unsigned i = 0; i < iconSnapshots.size(); ++i) {
- writeIconSnapshotToSQLDatabase(iconSnapshots[i]);
- LOG(IconDatabase, "Wrote IconRecord for IconURL %s with timeStamp of %i to the DB", urlForLogging(iconSnapshots[i].iconURL()).ascii().data(), iconSnapshots[i].timestamp());
+ for (auto& snapshot : iconSnapshots) {
+ writeIconSnapshotToSQLDatabase(snapshot);
+ LOG(IconDatabase, "Wrote IconRecord for IconURL %s with timeStamp of %i to the DB", urlForLogging(snapshot.iconURL()).ascii().data(), snapshot.timestamp());
}
- for (unsigned i = 0; i < pageSnapshots.size(); ++i) {
+ for (auto& snapshot : pageSnapshots) {
// If the icon URL is empty, this page is meant to be deleted
// ASSERTs are sanity checks to make sure the mappings exist if they should and don't if they shouldn't
- if (pageSnapshots[i].iconURL().isEmpty())
- removePageURLFromSQLDatabase(pageSnapshots[i].pageURL());
+ if (snapshot.iconURL().isEmpty())
+ removePageURLFromSQLDatabase(snapshot.pageURL());
else
- setIconURLForPageURLInSQLDatabase(pageSnapshots[i].iconURL(), pageSnapshots[i].pageURL());
- LOG(IconDatabase, "Committed IconURL for PageURL %s to database", urlForLogging(pageSnapshots[i].pageURL()).ascii().data());
+ setIconURLForPageURLInSQLDatabase(snapshot.iconURL(), snapshot.pageURL());
+ LOG(IconDatabase, "Committed IconURL for PageURL %s to database", urlForLogging(snapshot.pageURL()).ascii().data());
}
syncTransaction.commit();
@@ -1661,13 +1648,13 @@ void IconDatabase::pruneUnretainedIcons()
pageSQL.prepare();
int result;
- while ((result = pageSQL.step()) == SQLResultRow) {
- MutexLocker locker(m_urlAndIconLock);
+ while ((result = pageSQL.step()) == SQLITE_ROW) {
+ LockHolder locker(m_urlAndIconLock);
if (!m_pageURLToRecordMap.contains(pageSQL.getColumnText(1)))
pageIDsToDelete.append(pageSQL.getColumnInt64(0));
}
- if (result != SQLResultDone)
+ if (result != SQLITE_DONE)
LOG_ERROR("Error reading PageURL table from on-disk DB");
pageSQL.finalize();
@@ -1683,7 +1670,7 @@ void IconDatabase::pruneUnretainedIcons()
LOG(IconDatabase, "Pruning page with rowid %lli from disk", static_cast<long long>(pageIDsToDelete[i]));
pageDeleteSQL.bindInt64(1, pageIDsToDelete[i]);
int result = pageDeleteSQL.step();
- if (result != SQLResultDone)
+ if (result != SQLITE_DONE)
LOG_ERROR("Unabled to delete page with id %lli from disk", static_cast<long long>(pageIDsToDelete[i]));
pageDeleteSQL.reset();
@@ -1762,20 +1749,20 @@ void IconDatabase::deleteAllPreparedStatements()
{
ASSERT_ICON_SYNC_THREAD();
- m_setIconIDForPageURLStatement.clear();
- m_removePageURLStatement.clear();
- m_getIconIDForIconURLStatement.clear();
- m_getImageDataForIconURLStatement.clear();
- m_addIconToIconInfoStatement.clear();
- m_addIconToIconDataStatement.clear();
- m_getImageDataStatement.clear();
- m_deletePageURLsForIconURLStatement.clear();
- m_deleteIconFromIconInfoStatement.clear();
- m_deleteIconFromIconDataStatement.clear();
- m_updateIconInfoStatement.clear();
- m_updateIconDataStatement.clear();
- m_setIconInfoStatement.clear();
- m_setIconDataStatement.clear();
+ m_setIconIDForPageURLStatement = nullptr;
+ m_removePageURLStatement = nullptr;
+ m_getIconIDForIconURLStatement = nullptr;
+ m_getImageDataForIconURLStatement = nullptr;
+ m_addIconToIconInfoStatement = nullptr;
+ m_addIconToIconDataStatement = nullptr;
+ m_getImageDataStatement = nullptr;
+ m_deletePageURLsForIconURLStatement = nullptr;
+ m_deleteIconFromIconInfoStatement = nullptr;
+ m_deleteIconFromIconDataStatement = nullptr;
+ m_updateIconInfoStatement = nullptr;
+ m_updateIconDataStatement = nullptr;
+ m_setIconInfoStatement = nullptr;
+ m_setIconDataStatement = nullptr;
}
void* IconDatabase::cleanupSyncThread()
@@ -1795,7 +1782,7 @@ void* IconDatabase::cleanupSyncThread()
writeToDatabase();
// Close the database
- MutexLocker locker(m_syncLock);
+ LockHolder locker(m_syncLock);
m_databaseDirectory = String();
m_completeDatabasePath = String();
@@ -1807,23 +1794,23 @@ void* IconDatabase::cleanupSyncThread()
#endif
m_syncThreadRunning = false;
- return 0;
+ return nullptr;
}
// readySQLiteStatement() handles two things
// 1 - If the SQLDatabase& argument is different, the statement must be destroyed and remade. This happens when the user
// switches to and from private browsing
// 2 - Lazy construction of the Statement in the first place, in case we've never made this query before
-inline void readySQLiteStatement(OwnPtr<SQLiteStatement>& statement, SQLiteDatabase& db, const String& str)
+inline void readySQLiteStatement(std::unique_ptr<SQLiteStatement>& statement, SQLiteDatabase& db, const String& str)
{
- if (statement && (statement->database() != &db || statement->isExpired())) {
+ if (statement && (&statement->database() != &db || statement->isExpired())) {
if (statement->isExpired())
LOG(IconDatabase, "SQLiteStatement associated with %s is expired", str.ascii().data());
- statement.clear();
+ statement = nullptr;
}
if (!statement) {
- statement = adoptPtr(new SQLiteStatement(db, str));
- if (statement->prepare() != SQLResultOk)
+ statement = std::make_unique<SQLiteStatement>(db, str);
+ if (statement->prepare() != SQLITE_OK)
LOG_ERROR("Preparing statement %s failed", str.ascii().data());
}
}
@@ -1855,7 +1842,7 @@ void IconDatabase::setIconIDForPageURLInSQLDatabase(int64_t iconID, const String
m_setIconIDForPageURLStatement->bindInt64(2, iconID);
int result = m_setIconIDForPageURLStatement->step();
- if (result != SQLResultDone) {
+ if (result != SQLITE_DONE) {
ASSERT_NOT_REACHED();
LOG_ERROR("setIconIDForPageURLQuery failed for url %s", urlForLogging(pageURL).ascii().data());
}
@@ -1870,7 +1857,7 @@ void IconDatabase::removePageURLFromSQLDatabase(const String& pageURL)
readySQLiteStatement(m_removePageURLStatement, m_syncDB, "DELETE FROM PageURL WHERE url = (?);");
m_removePageURLStatement->bindText(1, pageURL);
- if (m_removePageURLStatement->step() != SQLResultDone)
+ if (m_removePageURLStatement->step() != SQLITE_DONE)
LOG_ERROR("removePageURLFromSQLDatabase failed for url %s", urlForLogging(pageURL).ascii().data());
m_removePageURLStatement->reset();
@@ -1885,10 +1872,10 @@ int64_t IconDatabase::getIconIDForIconURLFromSQLDatabase(const String& iconURL)
m_getIconIDForIconURLStatement->bindText(1, iconURL);
int64_t result = m_getIconIDForIconURLStatement->step();
- if (result == SQLResultRow)
+ if (result == SQLITE_ROW)
result = m_getIconIDForIconURLStatement->getColumnInt64(0);
else {
- if (result != SQLResultDone)
+ if (result != SQLITE_DONE)
LOG_ERROR("getIconIDForIconURLFromSQLDatabase failed for url %s", urlForLogging(iconURL).ascii().data());
result = 0;
}
@@ -1910,7 +1897,7 @@ int64_t IconDatabase::addIconURLToSQLDatabase(const String& iconURL)
int result = m_addIconToIconInfoStatement->step();
m_addIconToIconInfoStatement->reset();
- if (result != SQLResultDone) {
+ if (result != SQLITE_DONE) {
LOG_ERROR("addIconURLToSQLDatabase failed to insert %s into IconInfo", urlForLogging(iconURL).ascii().data());
return 0;
}
@@ -1921,7 +1908,7 @@ int64_t IconDatabase::addIconURLToSQLDatabase(const String& iconURL)
result = m_addIconToIconDataStatement->step();
m_addIconToIconDataStatement->reset();
- if (result != SQLResultDone) {
+ if (result != SQLITE_DONE) {
LOG_ERROR("addIconURLToSQLDatabase failed to insert %s into IconData", urlForLogging(iconURL).ascii().data());
return 0;
}
@@ -1929,7 +1916,7 @@ int64_t IconDatabase::addIconURLToSQLDatabase(const String& iconURL)
return iconID;
}
-PassRefPtr<SharedBuffer> IconDatabase::getImageDataForIconURLFromSQLDatabase(const String& iconURL)
+RefPtr<SharedBuffer> IconDatabase::getImageDataForIconURLFromSQLDatabase(const String& iconURL)
{
ASSERT_ICON_SYNC_THREAD();
@@ -1939,16 +1926,16 @@ PassRefPtr<SharedBuffer> IconDatabase::getImageDataForIconURLFromSQLDatabase(con
m_getImageDataForIconURLStatement->bindText(1, iconURL);
int result = m_getImageDataForIconURLStatement->step();
- if (result == SQLResultRow) {
+ if (result == SQLITE_ROW) {
Vector<char> data;
m_getImageDataForIconURLStatement->getColumnBlobAsVector(0, data);
imageData = SharedBuffer::create(data.data(), data.size());
- } else if (result != SQLResultDone)
+ } else if (result != SQLITE_DONE)
LOG_ERROR("getImageDataForIconURLFromSQLDatabase failed for url %s", urlForLogging(iconURL).ascii().data());
m_getImageDataForIconURLStatement->reset();
- return imageData.release();
+ return imageData;
}
void IconDatabase::removeIconFromSQLDatabase(const String& iconURL)
@@ -1970,21 +1957,21 @@ void IconDatabase::removeIconFromSQLDatabase(const String& iconURL)
readySQLiteStatement(m_deletePageURLsForIconURLStatement, m_syncDB, "DELETE FROM PageURL WHERE PageURL.iconID = (?);");
m_deletePageURLsForIconURLStatement->bindInt64(1, iconID);
- if (m_deletePageURLsForIconURLStatement->step() != SQLResultDone)
+ if (m_deletePageURLsForIconURLStatement->step() != SQLITE_DONE)
LOG_ERROR("m_deletePageURLsForIconURLStatement failed for url %s", urlForLogging(iconURL).ascii().data());
readySQLiteStatement(m_deleteIconFromIconInfoStatement, m_syncDB, "DELETE FROM IconInfo WHERE IconInfo.iconID = (?);");
m_deleteIconFromIconInfoStatement->bindInt64(1, iconID);
- if (m_deleteIconFromIconInfoStatement->step() != SQLResultDone)
+ if (m_deleteIconFromIconInfoStatement->step() != SQLITE_DONE)
LOG_ERROR("m_deleteIconFromIconInfoStatement failed for url %s", urlForLogging(iconURL).ascii().data());
-
+
readySQLiteStatement(m_deleteIconFromIconDataStatement, m_syncDB, "DELETE FROM IconData WHERE IconData.iconID = (?);");
m_deleteIconFromIconDataStatement->bindInt64(1, iconID);
- if (m_deleteIconFromIconDataStatement->step() != SQLResultDone)
+ if (m_deleteIconFromIconDataStatement->step() != SQLITE_DONE)
LOG_ERROR("m_deleteIconFromIconDataStatement failed for url %s", urlForLogging(iconURL).ascii().data());
-
+
m_deletePageURLsForIconURLStatement->reset();
m_deleteIconFromIconInfoStatement->reset();
m_deleteIconFromIconDataStatement->reset();
@@ -2018,7 +2005,7 @@ void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot)
m_updateIconInfoStatement->bindText(2, snapshot.iconURL());
m_updateIconInfoStatement->bindInt64(3, iconID);
- if (m_updateIconInfoStatement->step() != SQLResultDone)
+ if (m_updateIconInfoStatement->step() != SQLITE_DONE)
LOG_ERROR("Failed to update icon info for url %s", urlForLogging(snapshot.iconURL()).ascii().data());
m_updateIconInfoStatement->reset();
@@ -2033,7 +2020,7 @@ void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot)
else
m_updateIconDataStatement->bindNull(1);
- if (m_updateIconDataStatement->step() != SQLResultDone)
+ if (m_updateIconDataStatement->step() != SQLITE_DONE)
LOG_ERROR("Failed to update icon data for url %s", urlForLogging(snapshot.iconURL()).ascii().data());
m_updateIconDataStatement->reset();
@@ -2042,7 +2029,7 @@ void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot)
m_setIconInfoStatement->bindText(1, snapshot.iconURL());
m_setIconInfoStatement->bindInt64(2, snapshot.timestamp());
- if (m_setIconInfoStatement->step() != SQLResultDone)
+ if (m_setIconInfoStatement->step() != SQLITE_DONE)
LOG_ERROR("Failed to set icon info for url %s", urlForLogging(snapshot.iconURL()).ascii().data());
m_setIconInfoStatement->reset();
@@ -2059,7 +2046,7 @@ void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot)
else
m_setIconDataStatement->bindNull(2);
- if (m_setIconDataStatement->step() != SQLResultDone)
+ if (m_setIconDataStatement->step() != SQLITE_DONE)
LOG_ERROR("Failed to set icon data for url %s", urlForLogging(snapshot.iconURL()).ascii().data());
m_setIconDataStatement->reset();
@@ -2080,133 +2067,71 @@ void IconDatabase::setWasExcludedFromBackup()
SQLiteStatement(m_syncDB, "INSERT INTO IconDatabaseInfo (key, value) VALUES ('ExcludedFromBackup', 1)").executeCommand();
}
-class ClientWorkItem {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- ClientWorkItem(IconDatabaseClient* client)
- : m_client(client)
- { }
- virtual void performWork() = 0;
- virtual ~ClientWorkItem() { }
-
-protected:
- IconDatabaseClient* m_client;
-};
-
-class ImportedIconURLForPageURLWorkItem : public ClientWorkItem {
-public:
- ImportedIconURLForPageURLWorkItem(IconDatabaseClient* client, const String& pageURL)
- : ClientWorkItem(client)
- , m_pageURL(new String(pageURL.isolatedCopy()))
- { }
-
- virtual ~ImportedIconURLForPageURLWorkItem()
- {
- delete m_pageURL;
- }
-
- virtual void performWork()
- {
- ASSERT(m_client);
- m_client->didImportIconURLForPageURL(*m_pageURL);
- m_client = 0;
- }
-
-private:
- String* m_pageURL;
-};
-
-class ImportedIconDataForPageURLWorkItem : public ClientWorkItem {
-public:
- ImportedIconDataForPageURLWorkItem(IconDatabaseClient* client, const String& pageURL)
- : ClientWorkItem(client)
- , m_pageURL(new String(pageURL.isolatedCopy()))
- { }
-
- virtual ~ImportedIconDataForPageURLWorkItem()
- {
- delete m_pageURL;
- }
-
- virtual void performWork()
- {
- ASSERT(m_client);
- m_client->didImportIconDataForPageURL(*m_pageURL);
- m_client = 0;
- }
-
-private:
- String* m_pageURL;
-};
-
-class RemovedAllIconsWorkItem : public ClientWorkItem {
-public:
- RemovedAllIconsWorkItem(IconDatabaseClient* client)
- : ClientWorkItem(client)
- { }
-
- virtual void performWork()
- {
- ASSERT(m_client);
- m_client->didRemoveAllIcons();
- m_client = 0;
- }
-};
+void IconDatabase::checkClosedAfterMainThreadCallback()
+{
+ ASSERT_NOT_SYNC_THREAD();
-class FinishedURLImport : public ClientWorkItem {
-public:
- FinishedURLImport(IconDatabaseClient* client)
- : ClientWorkItem(client)
- { }
+ // If there are still callbacks in flight from the sync thread we cannot possibly be closed.
+ if (--m_mainThreadCallbackCount)
+ return;
- virtual void performWork()
- {
- ASSERT(m_client);
- m_client->didFinishURLImport();
- m_client = 0;
- }
-};
+ // Even if there's no more pending callbacks the database might otherwise still be open.
+ if (isOpenBesidesMainThreadCallbacks())
+ return;
-static void performWorkItem(void* context)
-{
- ClientWorkItem* item = static_cast<ClientWorkItem*>(context);
- item->performWork();
- delete item;
+ // This database is now actually closed! But first notify the client.
+ if (m_client)
+ m_client->didClose();
}
void IconDatabase::dispatchDidImportIconURLForPageURLOnMainThread(const String& pageURL)
{
ASSERT_ICON_SYNC_THREAD();
+ ++m_mainThreadCallbackCount;
- ImportedIconURLForPageURLWorkItem* work = new ImportedIconURLForPageURLWorkItem(m_client, pageURL);
- callOnMainThread(performWorkItem, work);
+ callOnMainThread([this, pageURL = pageURL.isolatedCopy()] {
+ if (m_client)
+ m_client->didImportIconURLForPageURL(pageURL);
+ checkClosedAfterMainThreadCallback();
+ });
}
void IconDatabase::dispatchDidImportIconDataForPageURLOnMainThread(const String& pageURL)
{
ASSERT_ICON_SYNC_THREAD();
+ ++m_mainThreadCallbackCount;
- ImportedIconDataForPageURLWorkItem* work = new ImportedIconDataForPageURLWorkItem(m_client, pageURL);
- callOnMainThread(performWorkItem, work);
+ callOnMainThread([this, pageURL = pageURL.isolatedCopy()] {
+ if (m_client)
+ m_client->didImportIconDataForPageURL(pageURL);
+ checkClosedAfterMainThreadCallback();
+ });
}
void IconDatabase::dispatchDidRemoveAllIconsOnMainThread()
{
ASSERT_ICON_SYNC_THREAD();
+ ++m_mainThreadCallbackCount;
- RemovedAllIconsWorkItem* work = new RemovedAllIconsWorkItem(m_client);
- callOnMainThread(performWorkItem, work);
+ callOnMainThread([this] {
+ if (m_client)
+ m_client->didRemoveAllIcons();
+ checkClosedAfterMainThreadCallback();
+ });
}
void IconDatabase::dispatchDidFinishURLImportOnMainThread()
{
ASSERT_ICON_SYNC_THREAD();
+ ++m_mainThreadCallbackCount;
- FinishedURLImport* work = new FinishedURLImport(m_client);
- callOnMainThread(performWorkItem, work);
+ callOnMainThread([this] {
+ if (m_client)
+ m_client->didFinishURLImport();
+ checkClosedAfterMainThreadCallback();
+ });
}
-
} // namespace WebCore
#endif // ENABLE(ICONDATABASE)
diff --git a/Source/WebCore/loader/icon/IconDatabase.h b/Source/WebCore/loader/icon/IconDatabase.h
index 04db323a7..061af4a12 100644
--- a/Source/WebCore/loader/icon/IconDatabase.h
+++ b/Source/WebCore/loader/icon/IconDatabase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
* Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -24,113 +24,101 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IconDatabase_h
-#define IconDatabase_h
+#pragma once
#include "IconDatabaseBase.h"
-#include "Timer.h"
-#include <wtf/HashCountedSet.h>
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
#if ENABLE(ICONDATABASE)
#include "SQLiteDatabase.h"
-#include <wtf/Threading.h>
-#endif // ENABLE(ICONDATABASE)
+#include "Timer.h"
+#include <wtf/Condition.h>
+#include <wtf/HashCountedSet.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#endif
namespace WebCore {
-class DocumentLoader;
-class Image;
-class IntSize;
-class IconDatabaseClient;
-class IconRecord;
-class IconSnapshot;
-class URL;
-class PageURLRecord;
-class PageURLSnapshot;
-class SharedBuffer;
-class SuddenTerminationDisabler;
+#if !ENABLE(ICONDATABASE)
-#if ENABLE(ICONDATABASE)
-class SQLTransaction;
-#endif
+// Dummy version of IconDatabase that does nothing.
+class IconDatabase final : public IconDatabaseBase {
+ WTF_MAKE_FAST_ALLOCATED;
-#if !ENABLE(ICONDATABASE)
-// For builds with IconDatabase disabled, they'll just use a default derivation of IconDatabaseBase. Which does nothing.
-class IconDatabase : public IconDatabaseBase {
public:
- static PassOwnPtr<IconDatabase> create() { return adoptPtr(new IconDatabase); }
static void delayDatabaseCleanup() { }
static void allowDatabaseCleanup() { }
static void checkIntegrityBeforeOpening() { }
- static String defaultDatabaseFilename() { return "WebpageIcons.db"; }
+
+ // FIXME: Is it really helpful to return a filename here rather than just the null string?
+ static String defaultDatabaseFilename() { return ASCIILiteral("WebpageIcons.db"); }
};
-#else
-class IconDatabase : public IconDatabaseBase {
+#else
+
+class IconRecord;
+class IconSnapshot;
+class PageURLRecord;
+class PageURLSnapshot;
+class SuddenTerminationDisabler;
+
+class IconDatabase final : public IconDatabaseBase {
WTF_MAKE_FAST_ALLOCATED;
// *** Main Thread Only ***
public:
- static PassOwnPtr<IconDatabase> create() { return adoptPtr(new IconDatabase); }
+ WEBCORE_EXPORT IconDatabase();
~IconDatabase();
- virtual void setClient(IconDatabaseClient*);
+ WEBCORE_EXPORT void setClient(IconDatabaseClient*) final;
- virtual bool open(const String& directory, const String& filename);
- virtual void close();
+ WEBCORE_EXPORT bool open(const String& directory, const String& filename) final;
+ WEBCORE_EXPORT void close() final;
- virtual void removeAllIcons();
+ WEBCORE_EXPORT void removeAllIcons() final;
void readIconForPageURLFromDisk(const String&);
- virtual Image* defaultIcon(const IntSize&);
+ WEBCORE_EXPORT Image* defaultIcon(const IntSize&) final;
- virtual void retainIconForPageURL(const String&);
- virtual void releaseIconForPageURL(const String&);
- virtual void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
- virtual void setIconURLForPageURL(const String& iconURL, const String& pageURL);
+ WEBCORE_EXPORT void retainIconForPageURL(const String&) final;
+ WEBCORE_EXPORT void releaseIconForPageURL(const String&) final;
+ WEBCORE_EXPORT void setIconDataForIconURL(SharedBuffer* data, const String& iconURL) final;
+ WEBCORE_EXPORT void setIconURLForPageURL(const String& iconURL, const String& pageURL) final;
- virtual Image* synchronousIconForPageURL(const String&, const IntSize&);
- virtual PassNativeImagePtr synchronousNativeIconForPageURL(const String& pageURLOriginal, const IntSize&);
- virtual String synchronousIconURLForPageURL(const String&);
- virtual bool synchronousIconDataKnownForIconURL(const String&);
- virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*);
-
- virtual void setEnabled(bool);
- virtual bool isEnabled() const;
-
- virtual void setPrivateBrowsingEnabled(bool flag);
+ WEBCORE_EXPORT Image* synchronousIconForPageURL(const String&, const IntSize&) final;
+ NativeImagePtr synchronousNativeIconForPageURL(const String& pageURLOriginal, const IntSize&) final;
+ WEBCORE_EXPORT String synchronousIconURLForPageURL(const String&) final;
+ bool synchronousIconDataKnownForIconURL(const String&) final;
+ WEBCORE_EXPORT IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*) final;
+
+ WEBCORE_EXPORT void setEnabled(bool);
+ WEBCORE_EXPORT bool isEnabled() const final;
+
+ WEBCORE_EXPORT void setPrivateBrowsingEnabled(bool flag) final;
bool isPrivateBrowsingEnabled() const;
-
- static void delayDatabaseCleanup();
- static void allowDatabaseCleanup();
- static void checkIntegrityBeforeOpening();
-
+
+ WEBCORE_EXPORT static void delayDatabaseCleanup();
+ WEBCORE_EXPORT static void allowDatabaseCleanup();
+ WEBCORE_EXPORT static void checkIntegrityBeforeOpening();
+
// Support for WebCoreStatistics in WebKit
- virtual size_t pageURLMappingCount();
- virtual size_t retainedPageURLCount();
- virtual size_t iconRecordCount();
- virtual size_t iconRecordCountWithData();
+ WEBCORE_EXPORT size_t pageURLMappingCount() final;
+ WEBCORE_EXPORT size_t retainedPageURLCount() final;
+ WEBCORE_EXPORT size_t iconRecordCount() final;
+ WEBCORE_EXPORT size_t iconRecordCountWithData() final;
private:
- IconDatabase();
friend IconDatabaseBase& iconDatabase();
- static void notifyPendingLoadDecisionsOnMainThread(void*);
void notifyPendingLoadDecisions();
void wakeSyncThread();
void scheduleOrDeferSyncTimer();
- void syncTimerFired(Timer<IconDatabase>&);
+ void syncTimerFired();
- Timer<IconDatabase> m_syncTimer;
+ Timer m_syncTimer;
ThreadIdentifier m_syncThread;
bool m_syncThreadRunning;
@@ -138,27 +126,24 @@ private:
RefPtr<IconRecord> m_defaultIconRecord;
- static void performScheduleOrDeferSyncTimerOnMainThread(void*);
- void performScheduleOrDeferSyncTimer();
-
bool m_scheduleOrDeferSyncTimerRequested;
std::unique_ptr<SuddenTerminationDisabler> m_disableSuddenTerminationWhileSyncTimerScheduled;
// *** Any Thread ***
public:
- virtual bool isOpen() const;
- virtual String databasePath() const;
- static String defaultDatabaseFilename();
+ WEBCORE_EXPORT bool isOpen() const final;
+ WEBCORE_EXPORT String databasePath() const final;
+ WEBCORE_EXPORT static String defaultDatabaseFilename();
private:
- PassRefPtr<IconRecord> getOrCreateIconRecord(const String& iconURL);
+ Ref<IconRecord> getOrCreateIconRecord(const String& iconURL);
PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
bool m_isEnabled;
bool m_privateBrowsingEnabled;
- mutable Mutex m_syncLock;
- ThreadCondition m_syncCondition;
+ mutable Lock m_syncLock;
+ Condition m_syncCondition;
String m_databaseDirectory;
// Holding m_syncLock is required when accessing m_completeDatabasePath
String m_completeDatabasePath;
@@ -169,24 +154,24 @@ private:
bool m_syncThreadHasWorkToDo;
std::unique_ptr<SuddenTerminationDisabler> m_disableSuddenTerminationWhileSyncThreadHasWorkToDo;
- Mutex m_urlAndIconLock;
+ Lock m_urlAndIconLock;
// Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
HashMap<String, IconRecord*> m_iconURLToRecordMap;
HashMap<String, PageURLRecord*> m_pageURLToRecordMap;
HashSet<String> m_retainedPageURLs;
- Mutex m_pendingSyncLock;
+ Lock m_pendingSyncLock;
// Holding m_pendingSyncLock is required when accessing any of the following data structures
HashMap<String, PageURLSnapshot> m_pageURLsPendingSync;
HashMap<String, IconSnapshot> m_iconsPendingSync;
- Mutex m_pendingReadingLock;
+ Lock m_pendingReadingLock;
// Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required
HashSet<String> m_pageURLsPendingImport;
HashSet<String> m_pageURLsInterestedInIcons;
HashSet<IconRecord*> m_iconsPendingReading;
- Mutex m_urlsToRetainOrReleaseLock;
+ Lock m_urlsToRetainOrReleaseLock;
// Holding m_urlsToRetainOrReleaseLock is required when accessing any of the following data structures.
HashCountedSet<String> m_urlsToRetain;
HashCountedSet<String> m_urlsToRelease;
@@ -194,7 +179,7 @@ private:
// *** Sync Thread Only ***
public:
- virtual bool shouldStopThreadActivity() const;
+ WEBCORE_EXPORT bool shouldStopThreadActivity() const final;
private:
static void iconDatabaseSyncThreadStart(void *);
@@ -219,6 +204,9 @@ private:
bool wasExcludedFromBackup();
void setWasExcludedFromBackup();
+ bool isOpenBesidesMainThreadCallbacks() const;
+ void checkClosedAfterMainThreadCallback();
+
bool m_initialPruningComplete;
void setIconURLForPageURLInSQLDatabase(const String&, const String&);
@@ -226,7 +214,7 @@ private:
void removePageURLFromSQLDatabase(const String& pageURL);
int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
int64_t addIconURLToSQLDatabase(const String&);
- PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
+ RefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
void removeIconFromSQLDatabase(const String& iconURL);
void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
@@ -237,30 +225,29 @@ private:
void dispatchDidImportIconDataForPageURLOnMainThread(const String&);
void dispatchDidRemoveAllIconsOnMainThread();
void dispatchDidFinishURLImportOnMainThread();
+ std::atomic<uint32_t> m_mainThreadCallbackCount;
// The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
IconDatabaseClient* m_client;
SQLiteDatabase m_syncDB;
- OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement;
- OwnPtr<SQLiteStatement> m_removePageURLStatement;
- OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement;
- OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement;
- OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement;
- OwnPtr<SQLiteStatement> m_addIconToIconDataStatement;
- OwnPtr<SQLiteStatement> m_getImageDataStatement;
- OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
- OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
- OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement;
- OwnPtr<SQLiteStatement> m_updateIconInfoStatement;
- OwnPtr<SQLiteStatement> m_updateIconDataStatement;
- OwnPtr<SQLiteStatement> m_setIconInfoStatement;
- OwnPtr<SQLiteStatement> m_setIconDataStatement;
+ std::unique_ptr<SQLiteStatement> m_setIconIDForPageURLStatement;
+ std::unique_ptr<SQLiteStatement> m_removePageURLStatement;
+ std::unique_ptr<SQLiteStatement> m_getIconIDForIconURLStatement;
+ std::unique_ptr<SQLiteStatement> m_getImageDataForIconURLStatement;
+ std::unique_ptr<SQLiteStatement> m_addIconToIconInfoStatement;
+ std::unique_ptr<SQLiteStatement> m_addIconToIconDataStatement;
+ std::unique_ptr<SQLiteStatement> m_getImageDataStatement;
+ std::unique_ptr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
+ std::unique_ptr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
+ std::unique_ptr<SQLiteStatement> m_deleteIconFromIconDataStatement;
+ std::unique_ptr<SQLiteStatement> m_updateIconInfoStatement;
+ std::unique_ptr<SQLiteStatement> m_updateIconDataStatement;
+ std::unique_ptr<SQLiteStatement> m_setIconInfoStatement;
+ std::unique_ptr<SQLiteStatement> m_setIconDataStatement;
};
#endif // !ENABLE(ICONDATABASE)
} // namespace WebCore
-
-#endif // IconDatabase_h
diff --git a/Source/WebCore/loader/icon/IconDatabaseBase.cpp b/Source/WebCore/loader/icon/IconDatabaseBase.cpp
index 51ccb3b27..4c6931071 100644
--- a/Source/WebCore/loader/icon/IconDatabaseBase.cpp
+++ b/Source/WebCore/loader/icon/IconDatabaseBase.cpp
@@ -10,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -47,7 +47,7 @@ bool IconDatabaseBase::open(const String&, const String&)
return false;
}
-static IconDatabaseBase* vmbase = 0;
+static IconDatabaseBase* vmbase = nullptr;
// Functions to get/set the global icon database.
IconDatabaseBase& iconDatabase()
@@ -55,7 +55,7 @@ IconDatabaseBase& iconDatabase()
if (vmbase)
return *vmbase;
- static IconDatabaseBase* defaultDatabase = 0;
+ static IconDatabaseBase* defaultDatabase = nullptr;
if (!defaultDatabase)
defaultDatabase = new IconDatabase;
diff --git a/Source/WebCore/loader/icon/IconDatabaseBase.h b/Source/WebCore/loader/icon/IconDatabaseBase.h
index e1f63af94..d4051b936 100644
--- a/Source/WebCore/loader/icon/IconDatabaseBase.h
+++ b/Source/WebCore/loader/icon/IconDatabaseBase.h
@@ -10,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -23,15 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IconDatabaseBase_h
-#define IconDatabaseBase_h
-
-#include "ImageSource.h"
-#include "SharedBuffer.h"
+#pragma once
+#include "NativeImage.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
@@ -39,12 +36,9 @@ class DocumentLoader;
class IconDatabaseClient;
class Image;
class IntSize;
+class SharedBuffer;
-enum IconLoadDecision {
- IconLoadYes,
- IconLoadNo,
- IconLoadUnknown
-};
+enum IconLoadDecision { IconLoadYes, IconLoadNo, IconLoadUnknown };
class CallbackBase : public RefCounted<CallbackBase> {
public:
@@ -79,9 +73,9 @@ class EnumCallback : public CallbackBase {
public:
typedef void (*CallbackFunction)(EnumType, void*);
- static PassRefPtr<EnumCallback> create(void* context, CallbackFunction callback)
+ static Ref<EnumCallback> create(void* context, CallbackFunction callback)
{
- return adoptRef(new EnumCallback(context, callback));
+ return adoptRef(*new EnumCallback(context, callback));
}
virtual ~EnumCallback()
@@ -94,12 +88,12 @@ public:
if (!m_callback)
return;
m_callback(result, context());
- m_callback = 0;
+ m_callback = nullptr;
}
void invalidate()
{
- m_callback = 0;
+ m_callback = nullptr;
}
private:
@@ -118,9 +112,9 @@ class ObjectCallback : public CallbackBase {
public:
typedef void (*CallbackFunction)(ObjectType, void*);
- static PassRefPtr<ObjectCallback> create(void* context, CallbackFunction callback)
+ static Ref<ObjectCallback> create(void* context, CallbackFunction callback)
{
- return adoptRef(new ObjectCallback(context, callback));
+ return adoptRef(*new ObjectCallback(context, callback));
}
virtual ~ObjectCallback()
@@ -133,12 +127,12 @@ public:
if (!m_callback)
return;
m_callback(result, context());
- m_callback = 0;
+ m_callback = nullptr;
}
-
+
void invalidate()
{
- m_callback = 0;
+ m_callback = nullptr;
}
private:
@@ -152,46 +146,42 @@ private:
CallbackFunction m_callback;
};
-typedef EnumCallback<IconLoadDecision> IconLoadDecisionCallback;
-typedef ObjectCallback<SharedBuffer*> IconDataCallback;
+using IconLoadDecisionCallback = EnumCallback<IconLoadDecision>;
+using IconDataCallback = ObjectCallback<SharedBuffer*>;
-class IconDatabaseBase {
+class WEBCORE_EXPORT IconDatabaseBase {
WTF_MAKE_NONCOPYABLE(IconDatabaseBase);
-protected:
- IconDatabaseBase() { }
-
public:
virtual ~IconDatabaseBase() { }
- // Used internally by WebCore
virtual bool isEnabled() const { return false; }
-
+
virtual void retainIconForPageURL(const String&) { }
virtual void releaseIconForPageURL(const String&) { }
- virtual void setIconURLForPageURL(const String&, const String&) { }
- virtual void setIconDataForIconURL(PassRefPtr<SharedBuffer>, const String&) { }
+ virtual void setIconURLForPageURL(const String& /*iconURL*/, const String& /*pageURL*/) { }
+ virtual void setIconDataForIconURL(SharedBuffer*, const String& /*iconURL*/) { }
// Synchronous calls used internally by WebCore.
// Usage should be replaced by asynchronous calls.
virtual String synchronousIconURLForPageURL(const String&);
virtual bool synchronousIconDataKnownForIconURL(const String&) { return false; }
virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*) { return IconLoadNo; }
- virtual Image* synchronousIconForPageURL(const String&, const IntSize&) { return 0; }
- virtual PassNativeImagePtr synchronousNativeIconForPageURL(const String&, const IntSize&) { return 0; }
+ virtual Image* synchronousIconForPageURL(const String&, const IntSize&) { return nullptr; }
+ virtual NativeImagePtr synchronousNativeIconForPageURL(const String&, const IntSize&) { return nullptr; }
// Asynchronous calls we should use to replace the above when supported.
virtual bool supportsAsynchronousMode() { return false; }
- virtual void loadDecisionForIconURL(const String&, PassRefPtr<IconLoadDecisionCallback>) { }
- virtual void iconDataForIconURL(const String&, PassRefPtr<IconDataCallback>) { }
-
+ virtual void loadDecisionForIconURL(const String&, IconLoadDecisionCallback&) { }
+ virtual void iconDataForIconURL(const String&, IconDataCallback&) { }
// Used within one or more WebKit ports.
// We should try to remove these dependencies from the IconDatabaseBase class.
+
virtual void setEnabled(bool) { }
- virtual Image* defaultIcon(const IntSize&) { return 0; }
+ virtual Image* defaultIcon(const IntSize&) { return nullptr; }
virtual size_t pageURLMappingCount() { return 0; }
virtual size_t retainedPageURLCount() { return 0; }
@@ -206,17 +196,17 @@ public:
virtual void setPrivateBrowsingEnabled(bool) { }
virtual void setClient(IconDatabaseClient*) { }
-
+
virtual bool isOpen() const { return false; }
virtual String databasePath() const;
+protected:
+ IconDatabaseBase() = default;
};
// Functions to get/set the global icon database.
-IconDatabaseBase& iconDatabase();
-void setGlobalIconDatabase(IconDatabaseBase*);
+WEBCORE_EXPORT IconDatabaseBase& iconDatabase();
+WEBCORE_EXPORT void setGlobalIconDatabase(IconDatabaseBase*);
bool documentCanHaveIcon(const String&);
} // namespace WebCore
-
-#endif // IconDatabaseBase_h
diff --git a/Source/WebCore/loader/icon/IconDatabaseClient.h b/Source/WebCore/loader/icon/IconDatabaseClient.h
index 70494ec11..33e5413a8 100644
--- a/Source/WebCore/loader/icon/IconDatabaseClient.h
+++ b/Source/WebCore/loader/icon/IconDatabaseClient.h
@@ -10,7 +10,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.
*
@@ -26,8 +26,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IconDatabaseClient_h
-#define IconDatabaseClient_h
+#pragma once
#include <wtf/Forward.h>
@@ -42,8 +41,7 @@ public:
virtual void didChangeIconForPageURL(const String&) = 0;
virtual void didRemoveAllIcons() = 0;
virtual void didFinishURLImport() = 0;
+ virtual void didClose() { }
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/loader/icon/IconLoader.cpp b/Source/WebCore/loader/icon/IconLoader.cpp
index 819bfb7e6..ab6385e55 100644
--- a/Source/WebCore/loader/icon/IconLoader.cpp
+++ b/Source/WebCore/loader/icon/IconLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -37,14 +37,21 @@
#include "IconController.h"
#include "IconDatabase.h"
#include "Logging.h"
-#include "ResourceBuffer.h"
#include "ResourceRequest.h"
+#include "SharedBuffer.h"
#include <wtf/text/CString.h>
namespace WebCore {
IconLoader::IconLoader(Frame& frame)
- : m_frame(frame)
+ : m_frame(&frame)
+ , m_url(frame.loader().icon().url())
+{
+}
+
+IconLoader::IconLoader(DocumentLoader& documentLoader, const URL& url)
+ : m_documentLoader(&documentLoader)
+ , m_url(url)
{
}
@@ -55,54 +62,83 @@ IconLoader::~IconLoader()
void IconLoader::startLoading()
{
- if (m_resource || !m_frame.document())
+ ASSERT(m_frame || m_documentLoader);
+
+ if (m_resource)
return;
- CachedResourceRequest request(ResourceRequest(m_frame.loader().icon().url()), ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, DoNotAllowStoredCredentials, DoNotAskClientForAnyCredentials, DoSecurityCheck, UseDefaultOriginRestrictionsForType));
+ if (m_frame && !m_frame->document())
+ return;
+
+
+ if (m_documentLoader && !m_documentLoader->frame())
+ return;
+
+ ResourceRequest resourceRequest = m_documentLoader ? m_url : m_frame->loader().icon().url();
+ resourceRequest.setPriority(ResourceLoadPriority::Low);
+#if !ERROR_DISABLED
+ // Copy this because we may want to access it after transferring the
+ // `resourceRequest` to the `request`. If we don't, then the LOG_ERROR
+ // below won't print a URL.
+ auto resourceRequestURL = resourceRequest.url();
+#endif
+
+ // ContentSecurityPolicyImposition::DoPolicyCheck is a placeholder value. It does not affect the request since Content Security Policy does not apply to raw resources.
+ CachedResourceRequest request(WTFMove(resourceRequest), ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, DoNotAllowStoredCredentials, ClientCredentialPolicy::CannotAskClientForCredentials, FetchOptions::Credentials::Omit, DoSecurityCheck, FetchOptions::Mode::NoCors, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching));
- request.mutableResourceRequest().setPriority(ResourceLoadPriorityLow);
request.setInitiator(cachedResourceRequestInitiators().icon);
- m_resource = m_frame.document()->cachedResourceLoader()->requestRawResource(request);
+ auto* frame = m_frame ? m_frame : m_documentLoader->frame();
+ m_resource = frame->document()->cachedResourceLoader().requestRawResource(WTFMove(request));
if (m_resource)
- m_resource->addClient(this);
+ m_resource->addClient(*this);
else
- LOG_ERROR("Failed to start load for icon at url %s", m_frame.loader().icon().url().string().ascii().data());
+ LOG_ERROR("Failed to start load for icon at url %s", resourceRequestURL.string().ascii().data());
}
void IconLoader::stopLoading()
{
if (m_resource) {
- m_resource->removeClient(this);
- m_resource = 0;
+ m_resource->removeClient(*this);
+ m_resource = nullptr;
}
}
-void IconLoader::notifyFinished(CachedResource* resource)
+void IconLoader::notifyFinished(CachedResource& resource)
{
- ASSERT(resource == m_resource);
+ ASSERT_UNUSED(resource, &resource == m_resource);
// If we got a status code indicating an invalid response, then lets
// ignore the data and not try to decode the error page as an icon.
- RefPtr<ResourceBuffer> data = resource->resourceBuffer();
- int status = resource->response().httpStatusCode();
+ auto* data = m_resource->resourceBuffer();
+ int status = m_resource->response().httpStatusCode();
if (status && (status < 200 || status > 299))
- data = 0;
+ data = nullptr;
static const char pdfMagicNumber[] = "%PDF";
static unsigned pdfMagicNumberLength = sizeof(pdfMagicNumber) - 1;
if (data && data->size() >= pdfMagicNumberLength && !memcmp(data->data(), pdfMagicNumber, pdfMagicNumberLength)) {
- LOG(IconDatabase, "IconLoader::finishLoading() - Ignoring icon at %s because it appears to be a PDF", resource->url().string().ascii().data());
- data = 0;
+ LOG(IconDatabase, "IconLoader::finishLoading() - Ignoring icon at %s because it appears to be a PDF", m_resource->url().string().ascii().data());
+ data = nullptr;
+ }
+
+ LOG(IconDatabase, "IconLoader::finishLoading() - Committing iconURL %s to database", m_resource->url().string().ascii().data());
+
+ if (!m_frame) {
+ // DocumentLoader::finishedLoadingIcon destroys this IconLoader as it finishes. This will automatically
+ // trigger IconLoader::stopLoading() during destruction, so we should just return here.
+ m_documentLoader->finishedLoadingIcon(*this, data);
+ return;
}
- LOG(IconDatabase, "IconLoader::finishLoading() - Committing iconURL %s to database", resource->url().string().ascii().data());
- m_frame.loader().icon().commitToDatabase(resource->url());
+ m_frame->loader().icon().commitToDatabase(m_resource->url());
+
// Setting the icon data only after committing to the database ensures that the data is
// kept in memory (so it does not have to be read from the database asynchronously), since
// there is a page URL referencing it.
- iconDatabase().setIconDataForIconURL(data ? data->sharedBuffer() : 0, resource->url().string());
- m_frame.loader().client().dispatchDidReceiveIcon();
+ iconDatabase().setIconDataForIconURL(data, m_resource->url().string());
+ m_frame->loader().client().dispatchDidReceiveIcon();
+
stopLoading();
}
diff --git a/Source/WebCore/loader/icon/IconLoader.h b/Source/WebCore/loader/icon/IconLoader.h
index 2fb79dc34..2de53e8e2 100644
--- a/Source/WebCore/loader/icon/IconLoader.h
+++ b/Source/WebCore/loader/icon/IconLoader.h
@@ -10,49 +10,50 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IconLoader_h
-#define IconLoader_h
+#pragma once
#include "CachedRawResourceClient.h"
#include "CachedResourceHandle.h"
+#include "URL.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
-#include <wtf/RefPtr.h>
namespace WebCore {
class CachedRawResource;
+class DocumentLoader;
class Frame;
class IconLoader final : private CachedRawResourceClient {
WTF_MAKE_NONCOPYABLE(IconLoader); WTF_MAKE_FAST_ALLOCATED;
public:
explicit IconLoader(Frame&);
+ IconLoader(DocumentLoader&, const URL&);
virtual ~IconLoader();
void startLoading();
void stopLoading();
private:
- virtual void notifyFinished(CachedResource*) override;
+ void notifyFinished(CachedResource&) final;
- Frame& m_frame;
+ Frame* m_frame { nullptr };
+ DocumentLoader* m_documentLoader { nullptr };
+ URL m_url;
CachedResourceHandle<CachedRawResource> m_resource;
};
} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/loader/icon/IconRecord.cpp b/Source/WebCore/loader/icon/IconRecord.cpp
index 7e90d8e8c..b20c26a32 100644
--- a/Source/WebCore/loader/icon/IconRecord.cpp
+++ b/Source/WebCore/loader/icon/IconRecord.cpp
@@ -10,7 +10,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.
*
@@ -62,16 +62,16 @@ Image* IconRecord::image(const IntSize&)
return m_image.get();
}
-void IconRecord::setImageData(PassRefPtr<SharedBuffer> data)
+void IconRecord::setImageData(RefPtr<SharedBuffer>&& data)
{
// It's okay to delete the raw image here. Any existing clients using this icon will be
// managing an image that was created with a copy of this raw image data.
m_image = BitmapImage::create();
// Copy the provided data into the buffer of the new Image object.
- if (!m_image->setData(data, true)) {
+ if (!m_image->setData(WTFMove(data), true)) {
LOG(IconDatabase, "Manual image data for iconURL '%s' FAILED - it was probably invalid image data", m_iconURL.ascii().data());
- m_image.clear();
+ m_image = nullptr;
}
m_dataSet = true;
diff --git a/Source/WebCore/loader/icon/IconRecord.h b/Source/WebCore/loader/icon/IconRecord.h
index e5a47f76e..f2105a39a 100644
--- a/Source/WebCore/loader/icon/IconRecord.h
+++ b/Source/WebCore/loader/icon/IconRecord.h
@@ -10,7 +10,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.
*
@@ -26,13 +26,11 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef IconRecord_h
-#define IconRecord_h
+#pragma once
#include "PageURLRecord.h"
#include "SharedBuffer.h"
#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
@@ -75,16 +73,16 @@ private:
class IconRecord : public RefCounted<IconRecord> {
friend class PageURLRecord;
public:
- static PassRefPtr<IconRecord> create(const String& url)
+ static Ref<IconRecord> create(const String& url)
{
- return adoptRef(new IconRecord(url));
+ return adoptRef(*new IconRecord(url));
}
~IconRecord();
time_t getTimestamp() { return m_stamp; }
void setTimestamp(time_t stamp) { m_stamp = stamp; }
- void setImageData(PassRefPtr<SharedBuffer> data);
+ void setImageData(RefPtr<SharedBuffer>&&);
Image* image(const IntSize&);
String iconURL() { return m_iconURL; }
@@ -119,7 +117,4 @@ private:
// SizeImageMap m_images;
};
-
} //namespace WebCore
-
-#endif
diff --git a/Source/WebCore/loader/icon/PageURLRecord.cpp b/Source/WebCore/loader/icon/PageURLRecord.cpp
index 09d649f83..99dded8f2 100644
--- a/Source/WebCore/loader/icon/PageURLRecord.cpp
+++ b/Source/WebCore/loader/icon/PageURLRecord.cpp
@@ -10,7 +10,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.
*
@@ -35,29 +35,29 @@ namespace WebCore {
PageURLRecord::PageURLRecord(const String& pageURL)
: m_pageURL(pageURL)
- , m_retainCount(0)
{
}
PageURLRecord::~PageURLRecord()
{
- setIconRecord(0);
+ if (m_iconRecord)
+ m_iconRecord->m_retainingPageURLs.remove(m_pageURL);
}
-void PageURLRecord::setIconRecord(PassRefPtr<IconRecord> icon)
+void PageURLRecord::setIconRecord(RefPtr<IconRecord>&& icon)
{
if (m_iconRecord)
m_iconRecord->m_retainingPageURLs.remove(m_pageURL);
-
- m_iconRecord = icon;
-
+
+ m_iconRecord = WTFMove(icon);
+
if (m_iconRecord)
m_iconRecord->m_retainingPageURLs.add(m_pageURL);
}
PageURLSnapshot PageURLRecord::snapshot(bool forDeletion) const
{
- return PageURLSnapshot(m_pageURL, (m_iconRecord && !forDeletion) ? m_iconRecord->iconURL() : String());
+ return { m_pageURL, (m_iconRecord && !forDeletion) ? m_iconRecord->iconURL() : String() };
}
} // namespace WebCore
diff --git a/Source/WebCore/loader/icon/PageURLRecord.h b/Source/WebCore/loader/icon/PageURLRecord.h
index 2b33808d3..189875e32 100644
--- a/Source/WebCore/loader/icon/PageURLRecord.h
+++ b/Source/WebCore/loader/icon/PageURLRecord.h
@@ -10,7 +10,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.
*
@@ -26,8 +26,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PageURLRecord_h
-#define PageURLRecord_h
+#pragma once
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
@@ -62,7 +61,7 @@ public:
inline String url() const { return m_pageURL; }
- void setIconRecord(PassRefPtr<IconRecord>);
+ void setIconRecord(RefPtr<IconRecord>&&);
IconRecord* iconRecord() { return m_iconRecord.get(); }
PageURLSnapshot snapshot(bool forDeletion = false) const;
@@ -83,13 +82,12 @@ public:
return m_retainCount > 0;
}
- inline int retainCount() const { return m_retainCount; }
+ int retainCount() const { return m_retainCount; }
+
private:
String m_pageURL;
RefPtr<IconRecord> m_iconRecord;
- int m_retainCount;
+ int m_retainCount { 0 };
};
-}
-
-#endif // PageURLRecord_h
+} // namespace WebCore