• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "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