/* * Copyright (C) 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved. * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef IconDatabase_h #define IconDatabase_h #include "IconDatabaseBase.h" #include #if ENABLE(ICONDATABASE) #include "SQLiteDatabase.h" #include "Timer.h" #include #include #include #include #endif namespace WebCore { #if !ENABLE(ICONDATABASE) // Dummy version of IconDatabase that does nothing. class IconDatabase final : public IconDatabaseBase { WTF_MAKE_FAST_ALLOCATED; public: static void delayDatabaseCleanup() { } static void allowDatabaseCleanup() { } static void checkIntegrityBeforeOpening() { } // FIXME: Is it really helpful to return a filename here rather than just the null string? static String defaultDatabaseFilename() { return ASCIILiteral("WebpageIcons.db"); } }; #else class IconRecord; class IconSnapshot; class PageURLRecord; class PageURLSnapshot; class SuddenTerminationDisabler; class IconDatabase final : public IconDatabaseBase { WTF_MAKE_FAST_ALLOCATED; // *** Main Thread Only *** public: WEBCORE_EXPORT IconDatabase(); ~IconDatabase(); WEBCORE_EXPORT virtual void setClient(IconDatabaseClient*) override; WEBCORE_EXPORT virtual bool open(const String& directory, const String& filename) override; WEBCORE_EXPORT virtual void close() override; WEBCORE_EXPORT virtual void removeAllIcons() override; void readIconForPageURLFromDisk(const String&); WEBCORE_EXPORT virtual Image* defaultIcon(const IntSize&) override; WEBCORE_EXPORT virtual void retainIconForPageURL(const String&) override; WEBCORE_EXPORT virtual void releaseIconForPageURL(const String&) override; WEBCORE_EXPORT virtual void setIconDataForIconURL(PassRefPtr data, const String&) override; WEBCORE_EXPORT virtual void setIconURLForPageURL(const String& iconURL, const String& pageURL) override; WEBCORE_EXPORT virtual Image* synchronousIconForPageURL(const String&, const IntSize&) override; virtual PassNativeImagePtr synchronousNativeIconForPageURL(const String& pageURLOriginal, const IntSize&) override; WEBCORE_EXPORT virtual String synchronousIconURLForPageURL(const String&) override; virtual bool synchronousIconDataKnownForIconURL(const String&) override; WEBCORE_EXPORT virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*) override; WEBCORE_EXPORT virtual void setEnabled(bool) override; WEBCORE_EXPORT virtual bool isEnabled() const override; WEBCORE_EXPORT virtual void setPrivateBrowsingEnabled(bool flag) override; bool isPrivateBrowsingEnabled() const; WEBCORE_EXPORT static void delayDatabaseCleanup(); WEBCORE_EXPORT static void allowDatabaseCleanup(); WEBCORE_EXPORT static void checkIntegrityBeforeOpening(); // Support for WebCoreStatistics in WebKit WEBCORE_EXPORT virtual size_t pageURLMappingCount() override; WEBCORE_EXPORT virtual size_t retainedPageURLCount() override; WEBCORE_EXPORT virtual size_t iconRecordCount() override; WEBCORE_EXPORT virtual size_t iconRecordCountWithData() override; private: friend IconDatabaseBase& iconDatabase(); void notifyPendingLoadDecisions(); void wakeSyncThread(); void scheduleOrDeferSyncTimer(); void syncTimerFired(); Timer m_syncTimer; ThreadIdentifier m_syncThread; bool m_syncThreadRunning; HashSet> m_loadersPendingDecision; RefPtr m_defaultIconRecord; bool m_scheduleOrDeferSyncTimerRequested; std::unique_ptr m_disableSuddenTerminationWhileSyncTimerScheduled; // *** Any Thread *** public: WEBCORE_EXPORT virtual bool isOpen() const override; WEBCORE_EXPORT virtual String databasePath() const override; WEBCORE_EXPORT static String defaultDatabaseFilename(); private: PassRefPtr getOrCreateIconRecord(const String& iconURL); PageURLRecord* getOrCreatePageURLRecord(const String& pageURL); bool m_isEnabled; bool m_privateBrowsingEnabled; mutable Lock m_syncLock; Condition m_syncCondition; String m_databaseDirectory; // Holding m_syncLock is required when accessing m_completeDatabasePath String m_completeDatabasePath; bool m_threadTerminationRequested; bool m_removeIconsRequested; bool m_iconURLImportComplete; bool m_syncThreadHasWorkToDo; std::unique_ptr m_disableSuddenTerminationWhileSyncThreadHasWorkToDo; Lock m_urlAndIconLock; // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain HashMap m_iconURLToRecordMap; HashMap m_pageURLToRecordMap; HashSet m_retainedPageURLs; Lock m_pendingSyncLock; // Holding m_pendingSyncLock is required when accessing any of the following data structures HashMap m_pageURLsPendingSync; HashMap m_iconsPendingSync; Lock m_pendingReadingLock; // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required HashSet m_pageURLsPendingImport; HashSet m_pageURLsInterestedInIcons; HashSet m_iconsPendingReading; Lock m_urlsToRetainOrReleaseLock; // Holding m_urlsToRetainOrReleaseLock is required when accessing any of the following data structures. HashCountedSet m_urlsToRetain; HashCountedSet m_urlsToRelease; bool m_retainOrReleaseIconRequested; // *** Sync Thread Only *** public: WEBCORE_EXPORT virtual bool shouldStopThreadActivity() const override; private: static void iconDatabaseSyncThreadStart(void *); void iconDatabaseSyncThread(); // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown void performOpenInitialization(); bool checkIntegrity(); void performURLImport(); void syncThreadMainLoop(); bool readFromDatabase(); bool writeToDatabase(); void pruneUnretainedIcons(); void checkForDanglingPageURLs(bool pruneIfFound); void removeAllIconsOnThread(); void deleteAllPreparedStatements(); void* cleanupSyncThread(); void performRetainIconForPageURL(const String&, int retainCount); void performReleaseIconForPageURL(const String&, int releaseCount); bool wasExcludedFromBackup(); void setWasExcludedFromBackup(); bool isOpenBesidesMainThreadCallbacks() const; void checkClosedAfterMainThreadCallback(); bool m_initialPruningComplete; void setIconURLForPageURLInSQLDatabase(const String&, const String&); void setIconIDForPageURLInSQLDatabase(int64_t, const String&); void removePageURLFromSQLDatabase(const String& pageURL); int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL); int64_t addIconURLToSQLDatabase(const String&); PassRefPtr getImageDataForIconURLFromSQLDatabase(const String& iconURL); void removeIconFromSQLDatabase(const String& iconURL); void writeIconSnapshotToSQLDatabase(const IconSnapshot&); void performPendingRetainAndReleaseOperations(); // Methods to dispatch client callbacks on the main thread void dispatchDidImportIconURLForPageURLOnMainThread(const String&); void dispatchDidImportIconDataForPageURLOnMainThread(const String&); void dispatchDidRemoveAllIconsOnMainThread(); void dispatchDidFinishURLImportOnMainThread(); std::atomic m_mainThreadCallbackCount; // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread IconDatabaseClient* m_client; SQLiteDatabase m_syncDB; std::unique_ptr m_setIconIDForPageURLStatement; std::unique_ptr m_removePageURLStatement; std::unique_ptr m_getIconIDForIconURLStatement; std::unique_ptr m_getImageDataForIconURLStatement; std::unique_ptr m_addIconToIconInfoStatement; std::unique_ptr m_addIconToIconDataStatement; std::unique_ptr m_getImageDataStatement; std::unique_ptr m_deletePageURLsForIconURLStatement; std::unique_ptr m_deleteIconFromIconInfoStatement; std::unique_ptr m_deleteIconFromIconDataStatement; std::unique_ptr m_updateIconInfoStatement; std::unique_ptr m_updateIconDataStatement; std::unique_ptr m_setIconInfoStatement; std::unique_ptr m_setIconDataStatement; }; #endif // !ENABLE(ICONDATABASE) } // namespace WebCore #endif // IconDatabase_h