⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icondatabase.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2006, 2007, 2008 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 COMPUTER, 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 COMPUTER, 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.  */#include "config.h"#include "IconDatabase.h"#include "AutodrainedPool.h"#include "CString.h"#include "DocumentLoader.h"#include "FileSystem.h"#include "IconDatabaseClient.h"#include "IconRecord.h"#include "Image.h"#include "IntSize.h"#include "KURL.h"#include "Logging.h"#include "PageURLRecord.h"#include "SQLiteStatement.h"#include "SQLiteTransaction.h"#include <runtime/InitializeThreading.h>#include <wtf/CurrentTime.h>#include <wtf/MainThread.h>#include <wtf/StdLibExtras.h>#if PLATFORM(WIN_OS)#include <windows.h>#include <winbase.h>#include <shlobj.h>#else#include <sys/stat.h>#endif#if PLATFORM(DARWIN)#include <pthread.h>#endif// For methods that are meant to support API from the main thread - should not be called internally#define ASSERT_NOT_SYNC_THREAD() ASSERT(!m_syncThreadRunning || !IS_ICON_SYNC_THREAD())// For methods that are meant to support the sync thread ONLY#define IS_ICON_SYNC_THREAD() (m_syncThread == currentThread())#define ASSERT_ICON_SYNC_THREAD() ASSERT(IS_ICON_SYNC_THREAD())#if PLATFORM(QT)#define CAN_THEME_URL_ICON#endifnamespace WebCore {static IconDatabase* sharedIconDatabase = 0;static int databaseCleanupCounter = 0;// This version number is in the DB and marks the current generation of the schema// Currently, a mismatched schema causes the DB to be wiped and reset.  This isn't // so bad during development but in the future, we would need to write a conversion// function to advance older released schemas to "current"const int currentDatabaseVersion = 6;// Icons expire once every 4 daysconst int iconExpirationTime = 60*60*24*4; const int updateTimerDelay = 5; static bool checkIntegrityOnOpen = false;#ifndef NDEBUGstatic String urlForLogging(const String& url){    static unsigned urlTruncationLength = 120;    if (url.length() < urlTruncationLength)        return url;    return url.substring(0, urlTruncationLength) + "...";}#endifstatic IconDatabaseClient* defaultClient() {    static IconDatabaseClient* defaultClient = new IconDatabaseClient();    return defaultClient;}IconDatabase* iconDatabase(){    if (!sharedIconDatabase) {        JSC::initializeThreading();        sharedIconDatabase = new IconDatabase;    }    return sharedIconDatabase;}// ************************// *** Main Thread Only ***// ************************void IconDatabase::setClient(IconDatabaseClient* client){    // We don't allow a null client, because we never null check it anywhere in this code    // Also don't allow a client change after the thread has already began     // (setting the client should occur before the database is opened)    ASSERT(client);    ASSERT(!m_syncThreadRunning);    if (!client || m_syncThreadRunning)        return;            m_client = client;}bool IconDatabase::open(const String& databasePath){    ASSERT_NOT_SYNC_THREAD();    if (!m_isEnabled)        return false;    if (isOpen()) {        LOG_ERROR("Attempt to reopen the IconDatabase which is already open.  Must close it first.");        return false;    }    m_databaseDirectory = databasePath.copy();    // Formulate the full path for the database file    m_completeDatabasePath = pathByAppendingComponent(m_databaseDirectory, defaultDatabaseFilename());    // Lock here as well as first thing in the thread so the thread doesn't actually commence until the createThread() call     // completes and m_syncThreadRunning is properly set    m_syncLock.lock();    m_syncThread = createThread(IconDatabase::iconDatabaseSyncThreadStart, this, "WebCore::IconDatabase");    m_syncLock.unlock();    if (!m_syncThread)        return false;    return true;}void IconDatabase::close(){    ASSERT_NOT_SYNC_THREAD();        if (m_syncThreadRunning) {        // Set the flag to tell the sync thread to wrap it up        m_threadTerminationRequested = true;        // Wake up the sync thread if it's waiting        wakeSyncThread();                // Wait for the sync thread to terminate        waitForThreadCompletion(m_syncThread, 0);    }    m_syncThreadRunning = false;        m_threadTerminationRequested = false;    m_removeIconsRequested = false;    m_syncDB.close();    ASSERT(!isOpen());}void IconDatabase::removeAllIcons(){    ASSERT_NOT_SYNC_THREAD();        if (!isOpen())        return;    LOG(IconDatabase, "Requesting background thread to remove all icons");        // Clear the in-memory record of every IconRecord, anything waiting to be read from disk, and anything waiting to be written to disk    {        MutexLocker locker(m_urlAndIconLock);                // Clear the IconRecords for every page URL - RefCounting will cause the IconRecords themselves to be deleted        // We don't delete the actual PageRecords because we have the "retain icon for url" count to keep track of        HashMap<String, PageURLRecord*>::iterator iter = m_pageURLToRecordMap.begin();        HashMap<String, PageURLRecord*>::iterator end = m_pageURLToRecordMap.end();        for (; iter != end; ++iter)            (*iter).second->setIconRecord(0);                    // Clear the iconURL -> IconRecord map        m_iconURLToRecordMap.clear();                            // Clear all in-memory records of things that need to be synced out to disk        {            MutexLocker locker(m_pendingSyncLock);            m_pageURLsPendingSync.clear();            m_iconsPendingSync.clear();        }                // Clear all in-memory records of things that need to be read in from disk        {            MutexLocker locker(m_pendingReadingLock);            m_pageURLsPendingImport.clear();            m_pageURLsInterestedInIcons.clear();            m_iconsPendingReading.clear();            m_loadersPendingDecision.clear();        }    }        m_removeIconsRequested = true;    wakeSyncThread();}Image* IconDatabase::iconForPageURL(const String& pageURLOriginal, const IntSize& size){       ASSERT_NOT_SYNC_THREAD();    // pageURLOriginal cannot be stored without being deep copied first.      // We should go our of our way to only copy it if we have to store it        if (!isOpen() || pageURLOriginal.isEmpty())        return defaultIcon(size);    MutexLocker locker(m_urlAndIconLock);        String pageURLCopy; // Creates a null string for easy testing        PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);    if (!pageRecord) {        pageURLCopy = pageURLOriginal.copy();        pageRecord = getOrCreatePageURLRecord(pageURLCopy);    }        // If pageRecord is NULL, one of two things is true -    // 1 - The initial url import is incomplete and this pageURL was marked to be notified once it is complete if an iconURL exists    // 2 - The initial url import IS complete and this pageURL has no icon    if (!pageRecord) {        MutexLocker locker(m_pendingReadingLock);                // Import is ongoing, there might be an icon.  In this case, register to be notified when the icon comes in        // If we ever reach this condition, we know we've already made the pageURL copy        if (!m_iconURLImportComplete)            m_pageURLsInterestedInIcons.add(pageURLCopy);                return 0;    }    IconRecord* iconRecord = pageRecord->iconRecord();        // If the initial URL import isn't complete, it's possible to have a PageURL record without an associated icon    // In this case, the pageURL is already in the set to alert the client when the iconURL mapping is complete so    // we can just bail now    if (!m_iconURLImportComplete && !iconRecord)        return 0;        // The only way we should *not* have an icon record is if this pageURL is retained but has no icon yet - make sure of that    ASSERT(iconRecord || m_retainedPageURLs.contains(pageURLOriginal));        if (!iconRecord)        return 0;            // If it's a new IconRecord object that doesn't have its imageData set yet,    // mark it to be read by the background thread    if (iconRecord->imageDataStatus() == ImageDataStatusUnknown) {        if (pageURLCopy.isNull())            pageURLCopy = pageURLOriginal.copy();            MutexLocker locker(m_pendingReadingLock);        m_pageURLsInterestedInIcons.add(pageURLCopy);        m_iconsPendingReading.add(iconRecord);        wakeSyncThread();        return 0;    }        // If the size parameter was (0, 0) that means the caller of this method just wanted the read from disk to be kicked off    // and isn't actually interested in the image return value    if (size == IntSize(0, 0))        return 0;            // PARANOID DISCUSSION: This method makes some assumptions.  It returns a WebCore::image which the icon database might dispose of at anytime in the future,    // and Images aren't ref counted.  So there is no way for the client to guarantee continued existence of the image.    // This has *always* been the case, but in practice clients would always create some other platform specific representation of the image    // and drop the raw Image*.  On Mac an NSImage, and on windows drawing into an HBITMAP.    // The async aspect adds a huge question - what if the image is deleted before the platform specific API has a chance to create its own    // representation out of it?    // If an image is read in from the icondatabase, we do *not* overwrite any image data that exists in the in-memory cache.      // This is because we make the assumption that anything in memory is newer than whatever is in the database.    // So the only time the data will be set from the second thread is when it is INITIALLY being read in from the database, but we would never     // delete the image on the secondary thread if the image already exists.    return iconRecord->image(size);}void IconDatabase::readIconForPageURLFromDisk(const String& pageURL){    // The effect of asking for an Icon for a pageURL automatically queues it to be read from disk    // if it hasn't already been set in memory.  The special IntSize (0, 0) is a special way of telling     // that method "I don't care about the actual Image, i just want you to make sure you're getting it from disk.    iconForPageURL(pageURL, IntSize(0,0));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -