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