1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2007 Justin Haygood (jhaygood (at) 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/HashMap.h> 33 #include <wtf/HashSet.h> 34 #include <wtf/Noncopyable.h> 35 #include <wtf/OwnPtr.h> 36 #include <wtf/PassOwnPtr.h> 37 #include <wtf/text/StringHash.h> 38 #include <wtf/text/WTFString.h> 39 40 #if ENABLE(ICONDATABASE) 41 #include "SQLiteDatabase.h" 42 #include <wtf/Threading.h> 43 #endif // ENABLE(ICONDATABASE) 44 45 namespace WebCore { 46 47 class DocumentLoader; 48 class Image; 49 class IntSize; 50 class IconDatabaseClient; 51 class IconRecord; 52 class IconSnapshot; 53 class KURL; 54 class PageURLRecord; 55 class PageURLSnapshot; 56 class SharedBuffer; 57 58 #if ENABLE(ICONDATABASE) 59 class SQLTransaction; 60 #endif 61 62 #if !ENABLE(ICONDATABASE) 63 // For builds with IconDatabase disabled, they'll just use a default derivation of IconDatabaseBase. Which does nothing. 64 class IconDatabase : public IconDatabaseBase { 65 public: 66 static void delayDatabaseCleanup() { } 67 static String defaultDatabaseFilename() { return "WebpageIcons.db"; } 68 }; 69 #else 70 71 class IconDatabase : public IconDatabaseBase { 72 WTF_MAKE_FAST_ALLOCATED; 73 74 // *** Main Thread Only *** 75 public: 76 static PassOwnPtr<IconDatabase> create() { return new IconDatabase; } 77 ~IconDatabase(); 78 79 virtual void setClient(IconDatabaseClient*); 80 81 virtual bool open(const String& directory, const String& filename); 82 virtual void close(); 83 84 virtual void removeAllIcons(); 85 86 void readIconForPageURLFromDisk(const String&); 87 88 virtual Image* defaultIcon(const IntSize&); 89 90 virtual void retainIconForPageURL(const String&); 91 virtual void releaseIconForPageURL(const String&); 92 virtual void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&); 93 virtual void setIconURLForPageURL(const String& iconURL, const String& pageURL); 94 95 virtual Image* synchronousIconForPageURL(const String&, const IntSize&); 96 virtual String synchronousIconURLForPageURL(const String&); 97 virtual bool synchronousIconDataKnownForIconURL(const String&); 98 virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*); 99 100 virtual void setEnabled(bool); 101 virtual bool isEnabled() const; 102 103 virtual void setPrivateBrowsingEnabled(bool flag); 104 bool isPrivateBrowsingEnabled() const; 105 106 static void delayDatabaseCleanup(); 107 static void allowDatabaseCleanup(); 108 static void checkIntegrityBeforeOpening(); 109 110 // Support for WebCoreStatistics in WebKit 111 virtual size_t pageURLMappingCount(); 112 virtual size_t retainedPageURLCount(); 113 virtual size_t iconRecordCount(); 114 virtual size_t iconRecordCountWithData(); 115 116 private: 117 IconDatabase(); 118 friend IconDatabaseBase& iconDatabase(); 119 120 static void notifyPendingLoadDecisionsOnMainThread(void*); 121 void notifyPendingLoadDecisions(); 122 123 void wakeSyncThread(); 124 void scheduleOrDeferSyncTimer(); 125 void syncTimerFired(Timer<IconDatabase>*); 126 127 Timer<IconDatabase> m_syncTimer; 128 ThreadIdentifier m_syncThread; 129 bool m_syncThreadRunning; 130 131 HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision; 132 133 RefPtr<IconRecord> m_defaultIconRecord; 134 135 // *** Any Thread *** 136 public: 137 virtual bool isOpen() const; 138 virtual String databasePath() const; 139 static String defaultDatabaseFilename(); 140 141 private: 142 PassRefPtr<IconRecord> getOrCreateIconRecord(const String& iconURL); 143 PageURLRecord* getOrCreatePageURLRecord(const String& pageURL); 144 145 bool m_isEnabled; 146 bool m_privateBrowsingEnabled; 147 148 mutable Mutex m_syncLock; 149 ThreadCondition m_syncCondition; 150 String m_databaseDirectory; 151 // Holding m_syncLock is required when accessing m_completeDatabasePath 152 String m_completeDatabasePath; 153 154 bool m_threadTerminationRequested; 155 bool m_removeIconsRequested; 156 bool m_iconURLImportComplete; 157 bool m_disabledSuddenTerminationForSyncThread; 158 159 Mutex m_urlAndIconLock; 160 // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain 161 HashMap<String, IconRecord*> m_iconURLToRecordMap; 162 HashMap<String, PageURLRecord*> m_pageURLToRecordMap; 163 HashSet<String> m_retainedPageURLs; 164 165 Mutex m_pendingSyncLock; 166 // Holding m_pendingSyncLock is required when accessing any of the following data structures 167 HashMap<String, PageURLSnapshot> m_pageURLsPendingSync; 168 HashMap<String, IconSnapshot> m_iconsPendingSync; 169 170 Mutex m_pendingReadingLock; 171 // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required 172 HashSet<String> m_pageURLsPendingImport; 173 HashSet<String> m_pageURLsInterestedInIcons; 174 HashSet<IconRecord*> m_iconsPendingReading; 175 176 // *** Sync Thread Only *** 177 public: 178 // Should be used only on the sync thread and only by the Safari 2 Icons import procedure 179 virtual void importIconURLForPageURL(const String& iconURL, const String& pageURL); 180 virtual void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL); 181 182 virtual bool shouldStopThreadActivity() const; 183 184 private: 185 static void* iconDatabaseSyncThreadStart(void *); 186 void* iconDatabaseSyncThread(); 187 188 // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database 189 // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown 190 void performOpenInitialization(); 191 bool checkIntegrity(); 192 void performURLImport(); 193 void* syncThreadMainLoop(); 194 bool readFromDatabase(); 195 bool writeToDatabase(); 196 void pruneUnretainedIcons(); 197 void checkForDanglingPageURLs(bool pruneIfFound); 198 void removeAllIconsOnThread(); 199 void deleteAllPreparedStatements(); 200 void* cleanupSyncThread(); 201 202 // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse) 203 bool imported(); 204 void setImported(bool); 205 206 bool wasExcludedFromBackup(); 207 void setWasExcludedFromBackup(); 208 209 bool m_initialPruningComplete; 210 211 void setIconURLForPageURLInSQLDatabase(const String&, const String&); 212 void setIconIDForPageURLInSQLDatabase(int64_t, const String&); 213 void removePageURLFromSQLDatabase(const String& pageURL); 214 int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL); 215 int64_t addIconURLToSQLDatabase(const String&); 216 PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL); 217 void removeIconFromSQLDatabase(const String& iconURL); 218 void writeIconSnapshotToSQLDatabase(const IconSnapshot&); 219 220 // Methods to dispatch client callbacks on the main thread 221 void dispatchDidImportIconURLForPageURLOnMainThread(const String&); 222 void dispatchDidImportIconDataForPageURLOnMainThread(const String&); 223 void dispatchDidRemoveAllIconsOnMainThread(); 224 void dispatchDidFinishURLImportOnMainThread(); 225 226 // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread 227 IconDatabaseClient* m_client; 228 229 SQLiteDatabase m_syncDB; 230 231 // Track whether the "Safari 2" import is complete and/or set in the database 232 bool m_imported; 233 bool m_isImportedSet; 234 235 OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement; 236 OwnPtr<SQLiteStatement> m_removePageURLStatement; 237 OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement; 238 OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement; 239 OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement; 240 OwnPtr<SQLiteStatement> m_addIconToIconDataStatement; 241 OwnPtr<SQLiteStatement> m_getImageDataStatement; 242 OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement; 243 OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement; 244 OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement; 245 OwnPtr<SQLiteStatement> m_updateIconInfoStatement; 246 OwnPtr<SQLiteStatement> m_updateIconDataStatement; 247 OwnPtr<SQLiteStatement> m_setIconInfoStatement; 248 OwnPtr<SQLiteStatement> m_setIconDataStatement; 249 }; 250 251 #endif // !ENABLE(ICONDATABASE) 252 253 } // namespace WebCore 254 255 #endif // IconDatabase_h 256