2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
27 #ifndef IconDatabase_h
28 #define IconDatabase_h
30 #if ENABLE(ICONDATABASE)
31 #include "SQLiteDatabase.h"
34 #include "StringHash.h"
35 #if ENABLE(ICONDATABASE)
36 #include "Threading.h"
39 #include <wtf/HashSet.h>
40 #include <wtf/Noncopyable.h>
41 #include <wtf/OwnPtr.h>
48 class IconDatabaseClient;
53 class PageURLSnapshot;
56 #if ENABLE(ICONDATABASE)
60 enum IconLoadDecision {
66 class IconDatabase : Noncopyable {
68 // *** Main Thread Only ***
70 void setClient(IconDatabaseClient*);
72 bool open(const String& path);
75 void removeAllIcons();
77 Image* iconForPageURL(const String&, const IntSize&, bool cache = true);
78 void readIconForPageURLFromDisk(const String&);
79 String iconURLForPageURL(const String&);
80 Image* defaultIcon(const IntSize&);
82 void retainIconForPageURL(const String&);
83 void releaseIconForPageURL(const String&);
85 void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
86 void setIconURLForPageURL(const String& iconURL, const String& pageURL);
88 IconLoadDecision loadDecisionForIconURL(const String&, DocumentLoader*);
89 bool iconDataKnownForIconURL(const String&);
91 void setEnabled(bool enabled);
92 bool isEnabled() const;
94 void setPrivateBrowsingEnabled(bool flag);
95 bool isPrivateBrowsingEnabled() const;
97 static void delayDatabaseCleanup();
98 static void allowDatabaseCleanup();
99 static void checkIntegrityBeforeOpening();
101 // Support for WebCoreStatistics in WebKit
102 size_t pageURLMappingCount();
103 size_t retainedPageURLCount();
104 size_t iconRecordCount();
105 size_t iconRecordCountWithData();
110 friend IconDatabase* iconDatabase();
112 #if ENABLE(ICONDATABASE)
113 // This is called on the main thread via the callOnMainThread() function which currently
114 // doesn't have any way to allow it to be an instance method, which it should be
115 static void notifyPendingLoadDecisions();
117 void notifyPendingLoadDecisionsInternal();
119 void wakeSyncThread();
120 void scheduleOrDeferSyncTimer();
121 OwnPtr<Timer<IconDatabase> > m_syncTimer;
122 void syncTimerFired(Timer<IconDatabase>*);
124 ThreadIdentifier m_syncThread;
125 bool m_syncThreadRunning;
127 HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision;
129 IconRecord* m_defaultIconRecord;
130 #endif // ENABLE(ICONDATABASE)
132 // *** Any Thread ***
135 String databasePath() const;
136 static String defaultDatabaseFilename();
139 #if ENABLE(ICONDATABASE)
140 IconRecord* getOrCreateIconRecord(const String& iconURL);
141 PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
144 bool m_privateBrowsingEnabled;
146 mutable Mutex m_syncLock;
147 ThreadCondition m_syncCondition;
148 String m_databaseDirectory;
149 // Holding m_syncLock is required when accessing m_completeDatabasePath
150 String m_completeDatabasePath;
152 bool m_threadTerminationRequested;
153 bool m_removeIconsRequested;
154 bool m_iconURLImportComplete;
156 Mutex m_urlAndIconLock;
157 // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
158 HashMap<String, IconRecord*> m_iconURLToRecordMap;
159 HashMap<String, PageURLRecord*> m_pageURLToRecordMap;
160 HashSet<String> m_retainedPageURLs;
162 Mutex m_pendingSyncLock;
163 // Holding m_pendingSyncLock is required when accessing any of the following data structures
164 HashMap<String, PageURLSnapshot> m_pageURLsPendingSync;
165 HashMap<String, IconSnapshot> m_iconsPendingSync;
167 Mutex m_pendingReadingLock;
168 // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required
169 HashSet<String> m_pageURLsPendingImport;
170 HashSet<String> m_pageURLsInterestedInIcons;
171 HashSet<IconRecord*> m_iconsPendingReading;
173 // *** Sync Thread Only ***
175 // Should be used only on the sync thread and only by the Safari 2 Icons import procedure
176 void importIconURLForPageURL(const String& iconURL, const String& pageURL);
177 void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
179 bool shouldStopThreadActivity() const;
182 static void* iconDatabaseSyncThreadStart(void *);
183 void* iconDatabaseSyncThread();
185 // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database
186 // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown
187 void performOpenInitialization();
188 bool checkIntegrity();
189 void performURLImport();
190 void* syncThreadMainLoop();
191 bool readFromDatabase();
192 bool writeToDatabase();
193 void pruneUnretainedIcons();
194 void checkForDanglingPageURLs(bool pruneIfFound);
195 void removeAllIconsOnThread();
196 void deleteAllPreparedStatements();
197 void* cleanupSyncThread();
199 // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse)
201 void setImported(bool);
203 bool m_initialPruningComplete;
205 void setIconURLForPageURLInSQLDatabase(const String&, const String&);
206 void setIconIDForPageURLInSQLDatabase(int64_t, const String&);
207 void removePageURLFromSQLDatabase(const String& pageURL);
208 int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
209 int64_t addIconURLToSQLDatabase(const String&);
210 PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
211 void removeIconFromSQLDatabase(const String& iconURL);
212 void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
214 // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
215 IconDatabaseClient* m_client;
217 SQLiteDatabase m_syncDB;
219 // Track whether the "Safari 2" import is complete and/or set in the database
221 bool m_isImportedSet;
223 OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement;
224 OwnPtr<SQLiteStatement> m_removePageURLStatement;
225 OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement;
226 OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement;
227 OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement;
228 OwnPtr<SQLiteStatement> m_addIconToIconDataStatement;
229 OwnPtr<SQLiteStatement> m_getImageDataStatement;
230 OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
231 OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
232 OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement;
233 OwnPtr<SQLiteStatement> m_updateIconInfoStatement;
234 OwnPtr<SQLiteStatement> m_updateIconDataStatement;
235 OwnPtr<SQLiteStatement> m_setIconInfoStatement;
236 OwnPtr<SQLiteStatement> m_setIconDataStatement;
237 #endif // ENABLE(ICONDATABASE)
240 // Function to obtain the global icon database.
241 IconDatabase* iconDatabase();
243 } // namespace WebCore