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