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