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