IconDatabase.h revision cad810f21b803229eb11403f9209855525a25d57
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 "Timer.h"
31#include <wtf/HashMap.h>
32#include <wtf/HashSet.h>
33#include <wtf/Noncopyable.h>
34#include <wtf/OwnPtr.h>
35#include <wtf/text/StringHash.h>
36
37#if ENABLE(ICONDATABASE)
38#include "SQLiteDatabase.h"
39#include <wtf/Threading.h>
40#endif
41
42namespace WebCore {
43
44class DocumentLoader;
45class Image;
46class IntSize;
47class IconDatabaseClient;
48class IconRecord;
49class IconSnapshot;
50class KURL;
51class PageURLRecord;
52class PageURLSnapshot;
53class SharedBuffer;
54
55#if ENABLE(ICONDATABASE)
56class SQLTransaction;
57#endif
58
59enum IconLoadDecision {
60    IconLoadYes,
61    IconLoadNo,
62    IconLoadUnknown
63};
64
65class IconDatabase : public Noncopyable {
66
67// *** Main Thread Only ***
68public:
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
106private:
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 ***
129public:
130    bool isOpen() const;
131    String databasePath() const;
132    static String defaultDatabaseFilename();
133
134#if ENABLE(ICONDATABASE)
135private:
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    bool m_disabledSuddenTerminationForSyncThread;
152
153    Mutex m_urlAndIconLock;
154    // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
155    HashMap<String, IconRecord*> m_iconURLToRecordMap;
156    HashMap<String, PageURLRecord*> m_pageURLToRecordMap;
157    HashSet<String> m_retainedPageURLs;
158
159    Mutex m_pendingSyncLock;
160    // Holding m_pendingSyncLock is required when accessing any of the following data structures
161    HashMap<String, PageURLSnapshot> m_pageURLsPendingSync;
162    HashMap<String, IconSnapshot> m_iconsPendingSync;
163
164    Mutex m_pendingReadingLock;
165    // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required
166    HashSet<String> m_pageURLsPendingImport;
167    HashSet<String> m_pageURLsInterestedInIcons;
168    HashSet<IconRecord*> m_iconsPendingReading;
169#endif // ENABLE(ICONDATABASE)
170
171// *** Sync Thread Only ***
172public:
173    // Should be used only on the sync thread and only by the Safari 2 Icons import procedure
174    void importIconURLForPageURL(const String& iconURL, const String& pageURL);
175    void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
176
177    bool shouldStopThreadActivity() const;
178
179#if ENABLE(ICONDATABASE)
180private:
181    static void* iconDatabaseSyncThreadStart(void *);
182    void* iconDatabaseSyncThread();
183
184    // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database
185    // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown
186    void performOpenInitialization();
187    bool checkIntegrity();
188    void performURLImport();
189    void* syncThreadMainLoop();
190    bool readFromDatabase();
191    bool writeToDatabase();
192    void pruneUnretainedIcons();
193    void checkForDanglingPageURLs(bool pruneIfFound);
194    void removeAllIconsOnThread();
195    void deleteAllPreparedStatements();
196    void* cleanupSyncThread();
197
198    // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse)
199    bool imported();
200    void setImported(bool);
201
202    bool m_initialPruningComplete;
203
204    void setIconURLForPageURLInSQLDatabase(const String&, const String&);
205    void setIconIDForPageURLInSQLDatabase(int64_t, const String&);
206    void removePageURLFromSQLDatabase(const String& pageURL);
207    int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
208    int64_t addIconURLToSQLDatabase(const String&);
209    PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
210    void removeIconFromSQLDatabase(const String& iconURL);
211    void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
212
213    // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
214    IconDatabaseClient* m_client;
215
216    SQLiteDatabase m_syncDB;
217
218    // Track whether the "Safari 2" import is complete and/or set in the database
219    bool m_imported;
220    bool m_isImportedSet;
221
222    OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement;
223    OwnPtr<SQLiteStatement> m_removePageURLStatement;
224    OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement;
225    OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement;
226    OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement;
227    OwnPtr<SQLiteStatement> m_addIconToIconDataStatement;
228    OwnPtr<SQLiteStatement> m_getImageDataStatement;
229    OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
230    OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
231    OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement;
232    OwnPtr<SQLiteStatement> m_updateIconInfoStatement;
233    OwnPtr<SQLiteStatement> m_updateIconDataStatement;
234    OwnPtr<SQLiteStatement> m_setIconInfoStatement;
235    OwnPtr<SQLiteStatement> m_setIconDataStatement;
236#endif // ENABLE(ICONDATABASE)
237};
238
239// Function to obtain the global icon database.
240IconDatabase* iconDatabase();
241
242} // namespace WebCore
243
244#endif // IconDatabase_h
245