1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
|
/*
* Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef IconDatabase_h
#define IconDatabase_h
#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)
namespace WebCore {
class DocumentLoader;
class Image;
class IntSize;
class IconDatabaseClient;
class IconRecord;
class IconSnapshot;
class KURL;
class PageURLRecord;
class PageURLSnapshot;
class SharedBuffer;
#if ENABLE(ICONDATABASE)
class SQLTransaction;
#endif
#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"; }
};
#else
class IconDatabase : public IconDatabaseBase {
WTF_MAKE_FAST_ALLOCATED;
// *** Main Thread Only ***
public:
static PassOwnPtr<IconDatabase> create() { return adoptPtr(new IconDatabase); }
~IconDatabase();
virtual void setClient(IconDatabaseClient*);
virtual bool open(const String& directory, const String& filename);
virtual void close();
virtual void removeAllIcons();
void readIconForPageURLFromDisk(const String&);
virtual Image* defaultIcon(const IntSize&);
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);
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);
bool isPrivateBrowsingEnabled() const;
static void delayDatabaseCleanup();
static void allowDatabaseCleanup();
static void checkIntegrityBeforeOpening();
// Support for WebCoreStatistics in WebKit
virtual size_t pageURLMappingCount();
virtual size_t retainedPageURLCount();
virtual size_t iconRecordCount();
virtual size_t iconRecordCountWithData();
private:
IconDatabase();
friend IconDatabaseBase& iconDatabase();
static void notifyPendingLoadDecisionsOnMainThread(void*);
void notifyPendingLoadDecisions();
void wakeSyncThread();
void scheduleOrDeferSyncTimer();
void syncTimerFired(Timer<IconDatabase>*);
Timer<IconDatabase> m_syncTimer;
ThreadIdentifier m_syncThread;
bool m_syncThreadRunning;
HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision;
RefPtr<IconRecord> m_defaultIconRecord;
static void performScheduleOrDeferSyncTimerOnMainThread(void*);
void performScheduleOrDeferSyncTimer();
bool m_scheduleOrDeferSyncTimerRequested;
// *** Any Thread ***
public:
virtual bool isOpen() const;
virtual String databasePath() const;
static String defaultDatabaseFilename();
private:
PassRefPtr<IconRecord> getOrCreateIconRecord(const String& iconURL);
PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
bool m_isEnabled;
bool m_privateBrowsingEnabled;
mutable Mutex m_syncLock;
ThreadCondition m_syncCondition;
String m_databaseDirectory;
// Holding m_syncLock is required when accessing m_completeDatabasePath
String m_completeDatabasePath;
bool m_threadTerminationRequested;
bool m_removeIconsRequested;
bool m_iconURLImportComplete;
bool m_syncThreadHasWorkToDo;
bool m_disabledSuddenTerminationForSyncThread;
Mutex 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;
// 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;
// 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;
// Holding m_urlsToRetainOrReleaseLock is required when accessing any of the following data structures.
HashCountedSet<String> m_urlsToRetain;
HashCountedSet<String> m_urlsToRelease;
bool m_retainOrReleaseIconRequested;
// *** Sync Thread Only ***
public:
virtual bool shouldStopThreadActivity() const;
private:
static void iconDatabaseSyncThreadStart(void *);
void iconDatabaseSyncThread();
// The following block of methods are called exclusively by the sync thread to manage i/o to and from the database
// Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown
void performOpenInitialization();
bool checkIntegrity();
void performURLImport();
void syncThreadMainLoop();
bool readFromDatabase();
bool writeToDatabase();
void pruneUnretainedIcons();
void checkForDanglingPageURLs(bool pruneIfFound);
void removeAllIconsOnThread();
void deleteAllPreparedStatements();
void* cleanupSyncThread();
void performRetainIconForPageURL(const String&, int retainCount);
void performReleaseIconForPageURL(const String&, int releaseCount);
bool wasExcludedFromBackup();
void setWasExcludedFromBackup();
bool m_initialPruningComplete;
void setIconURLForPageURLInSQLDatabase(const String&, const String&);
void setIconIDForPageURLInSQLDatabase(int64_t, const String&);
void removePageURLFromSQLDatabase(const String& pageURL);
int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
int64_t addIconURLToSQLDatabase(const String&);
PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
void removeIconFromSQLDatabase(const String& iconURL);
void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
void performPendingRetainAndReleaseOperations();
// Methods to dispatch client callbacks on the main thread
void dispatchDidImportIconURLForPageURLOnMainThread(const String&);
void dispatchDidImportIconDataForPageURLOnMainThread(const String&);
void dispatchDidRemoveAllIconsOnMainThread();
void dispatchDidFinishURLImportOnMainThread();
// 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;
};
#endif // !ENABLE(ICONDATABASE)
} // namespace WebCore
#endif // IconDatabase_h
|