12bde8e466a4451c7319e3a072d118917957d6554Steve Block/*
22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2011 Apple Inc. All rights reserved.
32bde8e466a4451c7319e3a072d118917957d6554Steve Block *
42bde8e466a4451c7319e3a072d118917957d6554Steve Block * Redistribution and use in source and binary forms, with or without
52bde8e466a4451c7319e3a072d118917957d6554Steve Block * modification, are permitted provided that the following conditions
62bde8e466a4451c7319e3a072d118917957d6554Steve Block * are met:
72bde8e466a4451c7319e3a072d118917957d6554Steve Block * 1. Redistributions of source code must retain the above copyright
82bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer.
92bde8e466a4451c7319e3a072d118917957d6554Steve Block * 2. Redistributions in binary form must reproduce the above copyright
102bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer in the
112bde8e466a4451c7319e3a072d118917957d6554Steve Block *    documentation and/or other materials provided with the distribution.
122bde8e466a4451c7319e3a072d118917957d6554Steve Block *
132bde8e466a4451c7319e3a072d118917957d6554Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
142bde8e466a4451c7319e3a072d118917957d6554Steve Block * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
152bde8e466a4451c7319e3a072d118917957d6554Steve Block * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
162bde8e466a4451c7319e3a072d118917957d6554Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
172bde8e466a4451c7319e3a072d118917957d6554Steve Block * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
182bde8e466a4451c7319e3a072d118917957d6554Steve Block * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
192bde8e466a4451c7319e3a072d118917957d6554Steve Block * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
202bde8e466a4451c7319e3a072d118917957d6554Steve Block * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
212bde8e466a4451c7319e3a072d118917957d6554Steve Block * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
222bde8e466a4451c7319e3a072d118917957d6554Steve Block * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
232bde8e466a4451c7319e3a072d118917957d6554Steve Block * THE POSSIBILITY OF SUCH DAMAGE.
242bde8e466a4451c7319e3a072d118917957d6554Steve Block */
252bde8e466a4451c7319e3a072d118917957d6554Steve Block
262bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "config.h"
272bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "StorageTracker.h"
282bde8e466a4451c7319e3a072d118917957d6554Steve Block
292bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(DOM_STORAGE)
302bde8e466a4451c7319e3a072d118917957d6554Steve Block
312bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "DatabaseThread.h"
322bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "FileSystem.h"
332bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "LocalStorageTask.h"
342bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "LocalStorageThread.h"
352bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "Logging.h"
362bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "PageGroup.h"
372bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "SQLiteFileSystem.h"
382bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "SQLiteStatement.h"
392bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "SecurityOrigin.h"
402bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "StorageTrackerClient.h"
412bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "TextEncoding.h"
422bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/MainThread.h>
432bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/StdLibExtras.h>
442bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/Vector.h>
452bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/text/CString.h>
462bde8e466a4451c7319e3a072d118917957d6554Steve Block
472bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace WebCore {
482bde8e466a4451c7319e3a072d118917957d6554Steve Block
492bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic StorageTracker* storageTracker = 0;
502bde8e466a4451c7319e3a072d118917957d6554Steve Block
512bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::initializeTracker(const String& storagePath)
522bde8e466a4451c7319e3a072d118917957d6554Steve Block{
532bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(isMainThread());
542bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!storageTracker);
552bde8e466a4451c7319e3a072d118917957d6554Steve Block
562bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!storageTracker)
572bde8e466a4451c7319e3a072d118917957d6554Steve Block        storageTracker = new StorageTracker(storagePath);
582bde8e466a4451c7319e3a072d118917957d6554Steve Block
592bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Make sure text encoding maps have been built on the main thread, as the StorageTracker thread might try to do it there instead.
602bde8e466a4451c7319e3a072d118917957d6554Steve Block    // FIXME (<rdar://problem/9127819>): Is there a more explicit way of doing this besides accessing the UTF8Encoding?
612bde8e466a4451c7319e3a072d118917957d6554Steve Block    UTF8Encoding();
622bde8e466a4451c7319e3a072d118917957d6554Steve Block
632bde8e466a4451c7319e3a072d118917957d6554Steve Block    SQLiteFileSystem::registerSQLiteVFS();
642bde8e466a4451c7319e3a072d118917957d6554Steve Block    storageTracker->setIsActive(true);
652bde8e466a4451c7319e3a072d118917957d6554Steve Block    storageTracker->m_thread->start();
662bde8e466a4451c7319e3a072d118917957d6554Steve Block    storageTracker->importOriginIdentifiers();
672bde8e466a4451c7319e3a072d118917957d6554Steve Block}
682bde8e466a4451c7319e3a072d118917957d6554Steve Block
692bde8e466a4451c7319e3a072d118917957d6554Steve BlockStorageTracker& StorageTracker::tracker()
702bde8e466a4451c7319e3a072d118917957d6554Steve Block{
712bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!storageTracker)
722bde8e466a4451c7319e3a072d118917957d6554Steve Block        storageTracker = new StorageTracker("");
732bde8e466a4451c7319e3a072d118917957d6554Steve Block
742bde8e466a4451c7319e3a072d118917957d6554Steve Block    return *storageTracker;
752bde8e466a4451c7319e3a072d118917957d6554Steve Block}
762bde8e466a4451c7319e3a072d118917957d6554Steve Block
772bde8e466a4451c7319e3a072d118917957d6554Steve BlockStorageTracker::StorageTracker(const String& storagePath)
782bde8e466a4451c7319e3a072d118917957d6554Steve Block    : m_client(0)
792bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_thread(LocalStorageThread::create())
802bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_isActive(false)
812bde8e466a4451c7319e3a072d118917957d6554Steve Block{
822bde8e466a4451c7319e3a072d118917957d6554Steve Block    setStorageDirectoryPath(storagePath);
832bde8e466a4451c7319e3a072d118917957d6554Steve Block}
842bde8e466a4451c7319e3a072d118917957d6554Steve Block
852bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::setStorageDirectoryPath(const String& path)
862bde8e466a4451c7319e3a072d118917957d6554Steve Block{
872bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockDatabase(m_databaseGuard);
882bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!m_database.isOpen());
892bde8e466a4451c7319e3a072d118917957d6554Steve Block
902bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_storageDirectoryPath = path.threadsafeCopy();
912bde8e466a4451c7319e3a072d118917957d6554Steve Block}
922bde8e466a4451c7319e3a072d118917957d6554Steve Block
932bde8e466a4451c7319e3a072d118917957d6554Steve BlockString StorageTracker::trackerDatabasePath()
942bde8e466a4451c7319e3a072d118917957d6554Steve Block{
952bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!m_databaseGuard.tryLock());
962bde8e466a4451c7319e3a072d118917957d6554Steve Block    return SQLiteFileSystem::appendDatabaseFileNameToPath(m_storageDirectoryPath, "StorageTracker.db");
972bde8e466a4451c7319e3a072d118917957d6554Steve Block}
982bde8e466a4451c7319e3a072d118917957d6554Steve Block
992bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::openTrackerDatabase(bool createIfDoesNotExist)
1002bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1012bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_isActive);
1022bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!isMainThread());
1032bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!m_databaseGuard.tryLock());
1042bde8e466a4451c7319e3a072d118917957d6554Steve Block
1052bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_database.isOpen())
1062bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1072bde8e466a4451c7319e3a072d118917957d6554Steve Block
1082bde8e466a4451c7319e3a072d118917957d6554Steve Block    String databasePath = trackerDatabasePath();
1092bde8e466a4451c7319e3a072d118917957d6554Steve Block
1102bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!SQLiteFileSystem::ensureDatabaseFileExists(databasePath, createIfDoesNotExist)) {
1112bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (createIfDoesNotExist)
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block            LOG_ERROR("Failed to create database file '%s'", databasePath.ascii().data());
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1152bde8e466a4451c7319e3a072d118917957d6554Steve Block
1162bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_database.open(databasePath)) {
1172bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Failed to open databasePath %s.", databasePath.ascii().data());
1182bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1192bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_database.disableThreadingChecks();
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block
1232bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_database.tableExists("Origins")) {
1242bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, path TEXT);"))
1252bde8e466a4451c7319e3a072d118917957d6554Steve Block            LOG_ERROR("Failed to create Origins table.");
1262bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1272bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block
1292bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::importOriginIdentifiers()
1302bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1312bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_isActive)
1322bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1332bde8e466a4451c7319e3a072d118917957d6554Steve Block
1342bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(isMainThread());
1352bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_thread);
1362bde8e466a4451c7319e3a072d118917957d6554Steve Block
1372bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_thread->scheduleTask(LocalStorageTask::createOriginIdentifiersImport());
1382bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1392bde8e466a4451c7319e3a072d118917957d6554Steve Block
1402bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::syncImportOriginIdentifiers()
1412bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1422bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_isActive);
1432bde8e466a4451c7319e3a072d118917957d6554Steve Block
1442bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!isMainThread());
1452bde8e466a4451c7319e3a072d118917957d6554Steve Block
1462bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
1472bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockDatabase(m_databaseGuard);
1482bde8e466a4451c7319e3a072d118917957d6554Steve Block
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Don't force creation of StorageTracker's db just because a tracker
1502bde8e466a4451c7319e3a072d118917957d6554Steve Block        // was initialized. It will be created if local storage dbs are found
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block        // by syncFileSystemAndTrackerDatabse() or the next time a local storage
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block        // db is created by StorageAreaSync.
1532bde8e466a4451c7319e3a072d118917957d6554Steve Block        openTrackerDatabase(false);
1542bde8e466a4451c7319e3a072d118917957d6554Steve Block
1552bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (m_database.isOpen()) {
1562bde8e466a4451c7319e3a072d118917957d6554Steve Block            SQLiteStatement statement(m_database, "SELECT origin FROM Origins");
1572bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (statement.prepare() != SQLResultOk) {
1582bde8e466a4451c7319e3a072d118917957d6554Steve Block                LOG_ERROR("Failed to prepare statement.");
1592bde8e466a4451c7319e3a072d118917957d6554Steve Block                return;
1602bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
1612bde8e466a4451c7319e3a072d118917957d6554Steve Block
1622bde8e466a4451c7319e3a072d118917957d6554Steve Block            int result;
1632bde8e466a4451c7319e3a072d118917957d6554Steve Block
1642bde8e466a4451c7319e3a072d118917957d6554Steve Block            {
1652bde8e466a4451c7319e3a072d118917957d6554Steve Block                MutexLocker lockOrigins(m_originSetGuard);
1662bde8e466a4451c7319e3a072d118917957d6554Steve Block                while ((result = statement.step()) == SQLResultRow)
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block                    m_originSet.add(statement.getColumnText(0).threadsafeCopy());
1682bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
1692bde8e466a4451c7319e3a072d118917957d6554Steve Block
1702bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (result != SQLResultDone) {
1712bde8e466a4451c7319e3a072d118917957d6554Steve Block                LOG_ERROR("Failed to read in all origins from the database.");
1722bde8e466a4451c7319e3a072d118917957d6554Steve Block                return;
1732bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
1742bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
1752bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1762bde8e466a4451c7319e3a072d118917957d6554Steve Block
1772bde8e466a4451c7319e3a072d118917957d6554Steve Block    syncFileSystemAndTrackerDatabase();
1782bde8e466a4451c7319e3a072d118917957d6554Steve Block
1792bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
1802bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockClient(m_clientGuard);
1812bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (m_client) {
1822bde8e466a4451c7319e3a072d118917957d6554Steve Block            MutexLocker lockOrigins(m_originSetGuard);
1832bde8e466a4451c7319e3a072d118917957d6554Steve Block            OriginSet::const_iterator end = m_originSet.end();
1842bde8e466a4451c7319e3a072d118917957d6554Steve Block            for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
1852bde8e466a4451c7319e3a072d118917957d6554Steve Block                m_client->dispatchDidModifyOrigin(*it);
1862bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
1872bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1882bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1892bde8e466a4451c7319e3a072d118917957d6554Steve Block
1902bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::syncFileSystemAndTrackerDatabase()
1912bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1922bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!isMainThread());
1932bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_isActive);
1942bde8e466a4451c7319e3a072d118917957d6554Steve Block
1952bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_databaseGuard.lock();
1962bde8e466a4451c7319e3a072d118917957d6554Steve Block    DEFINE_STATIC_LOCAL(const String, fileMatchPattern, ("*.localstorage"));
1972bde8e466a4451c7319e3a072d118917957d6554Steve Block    DEFINE_STATIC_LOCAL(const String, fileExt, (".localstorage"));
1982bde8e466a4451c7319e3a072d118917957d6554Steve Block    DEFINE_STATIC_LOCAL(const unsigned, fileExtLength, (fileExt.length()));
1992bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_databaseGuard.unlock();
2002bde8e466a4451c7319e3a072d118917957d6554Steve Block
2012bde8e466a4451c7319e3a072d118917957d6554Steve Block    Vector<String> paths;
2022bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2032bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lock(m_databaseGuard);
2042bde8e466a4451c7319e3a072d118917957d6554Steve Block        paths = listDirectory(m_storageDirectoryPath, fileMatchPattern);
2052bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2062bde8e466a4451c7319e3a072d118917957d6554Steve Block
2072bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Use a copy of m_originSet to find expired entries and to schedule their
2082bde8e466a4451c7319e3a072d118917957d6554Steve Block    // deletions from disk and from m_originSet.
2092bde8e466a4451c7319e3a072d118917957d6554Steve Block    OriginSet originSetCopy;
2102bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2112bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lock(m_originSetGuard);
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block        OriginSet::const_iterator end = m_originSet.end();
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block            originSetCopy.add((*it).threadsafeCopy());
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2162bde8e466a4451c7319e3a072d118917957d6554Steve Block
2172bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Add missing StorageTracker records.
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block    OriginSet foundOrigins;
2192bde8e466a4451c7319e3a072d118917957d6554Steve Block    Vector<String>::const_iterator end = paths.end();
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (Vector<String>::const_iterator it = paths.begin(); it != end; ++it) {
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block        String path = *it;
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (path.endsWith(fileExt, true) && path.length() > fileExtLength) {
2232bde8e466a4451c7319e3a072d118917957d6554Steve Block            String file = pathGetFileName(path);
2242bde8e466a4451c7319e3a072d118917957d6554Steve Block            String originIdentifier = file.substring(0, file.length() - fileExtLength);
2252bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!originSetCopy.contains(originIdentifier))
2262bde8e466a4451c7319e3a072d118917957d6554Steve Block                syncSetOriginDetails(originIdentifier, path);
2272bde8e466a4451c7319e3a072d118917957d6554Steve Block
2282bde8e466a4451c7319e3a072d118917957d6554Steve Block            foundOrigins.add(originIdentifier);
2292bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
2302bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2312bde8e466a4451c7319e3a072d118917957d6554Steve Block
2322bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Delete stale StorageTracker records.
2332bde8e466a4451c7319e3a072d118917957d6554Steve Block    OriginSet::const_iterator setEnd = originSetCopy.end();
2342bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (OriginSet::const_iterator it = originSetCopy.begin(); it != setEnd; ++it) {
2352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!foundOrigins.contains(*it)) {
2362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            RefPtr<StringImpl> originIdentifier = (*it).threadsafeCopy().impl();
2372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            callOnMainThread(deleteOriginOnMainThread, originIdentifier.release().leakRef());
2382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
2392bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2402bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2412bde8e466a4451c7319e3a072d118917957d6554Steve Block
2422bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::setOriginDetails(const String& originIdentifier, const String& databaseFile)
2432bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2442bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_isActive)
2452bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
2462bde8e466a4451c7319e3a072d118917957d6554Steve Block
2472bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2482bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockOrigins(m_originSetGuard);
2492bde8e466a4451c7319e3a072d118917957d6554Steve Block
2502bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (m_originSet.contains(originIdentifier))
2512bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
2522bde8e466a4451c7319e3a072d118917957d6554Steve Block
2532bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_originSet.add(originIdentifier);
2542bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2552bde8e466a4451c7319e3a072d118917957d6554Steve Block
2562bde8e466a4451c7319e3a072d118917957d6554Steve Block    OwnPtr<LocalStorageTask> task = LocalStorageTask::createSetOriginDetails(originIdentifier.threadsafeCopy(), databaseFile);
2572bde8e466a4451c7319e3a072d118917957d6554Steve Block
2582bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isMainThread()) {
2592bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(m_thread);
2602bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_thread->scheduleTask(task.release());
2612bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else
2622bde8e466a4451c7319e3a072d118917957d6554Steve Block        callOnMainThread(scheduleTask, reinterpret_cast<void*>(task.leakPtr()));
2632bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2642bde8e466a4451c7319e3a072d118917957d6554Steve Block
2652bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::scheduleTask(void* taskIn)
2662bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2672bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(isMainThread());
2682bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(StorageTracker::tracker().m_thread);
2692bde8e466a4451c7319e3a072d118917957d6554Steve Block
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block    OwnPtr<LocalStorageTask> task = adoptPtr(reinterpret_cast<LocalStorageTask*>(taskIn));
2712bde8e466a4451c7319e3a072d118917957d6554Steve Block
2722bde8e466a4451c7319e3a072d118917957d6554Steve Block    StorageTracker::tracker().m_thread->scheduleTask(task.release());
2732bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2742bde8e466a4451c7319e3a072d118917957d6554Steve Block
2752bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::syncSetOriginDetails(const String& originIdentifier, const String& databaseFile)
2762bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2772bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!isMainThread());
2782bde8e466a4451c7319e3a072d118917957d6554Steve Block
2792bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockDatabase(m_databaseGuard);
2802bde8e466a4451c7319e3a072d118917957d6554Steve Block
2812bde8e466a4451c7319e3a072d118917957d6554Steve Block    openTrackerDatabase(true);
2822bde8e466a4451c7319e3a072d118917957d6554Steve Block
2832bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_database.isOpen())
2842bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
2852bde8e466a4451c7319e3a072d118917957d6554Steve Block
2862bde8e466a4451c7319e3a072d118917957d6554Steve Block    SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)");
2872bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (statement.prepare() != SQLResultOk) {
2882bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.ascii().data());
2892bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
2902bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2912bde8e466a4451c7319e3a072d118917957d6554Steve Block
2922bde8e466a4451c7319e3a072d118917957d6554Steve Block    statement.bindText(1, originIdentifier);
2932bde8e466a4451c7319e3a072d118917957d6554Steve Block    statement.bindText(2, databaseFile);
2942bde8e466a4451c7319e3a072d118917957d6554Steve Block
2952bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (statement.step() != SQLResultDone)
2962bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.ascii().data());
2972bde8e466a4451c7319e3a072d118917957d6554Steve Block
2982bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2992bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockOrigins(m_originSetGuard);
3002bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!m_originSet.contains(originIdentifier))
3012bde8e466a4451c7319e3a072d118917957d6554Steve Block            m_originSet.add(originIdentifier);
3022bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3032bde8e466a4451c7319e3a072d118917957d6554Steve Block
3042bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
3052bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockClient(m_clientGuard);
3062bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (m_client)
3072bde8e466a4451c7319e3a072d118917957d6554Steve Block            m_client->dispatchDidModifyOrigin(originIdentifier);
3082bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3092bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3102bde8e466a4451c7319e3a072d118917957d6554Steve Block
3112bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::origins(Vector<RefPtr<SecurityOrigin> >& result)
3122bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3132bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_isActive);
3142bde8e466a4451c7319e3a072d118917957d6554Steve Block
3152bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_isActive)
3162bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3172bde8e466a4451c7319e3a072d118917957d6554Steve Block
3182bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockOrigins(m_originSetGuard);
3192bde8e466a4451c7319e3a072d118917957d6554Steve Block
3202bde8e466a4451c7319e3a072d118917957d6554Steve Block    OriginSet::const_iterator end = m_originSet.end();
3212bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
3222bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.append(SecurityOrigin::createFromDatabaseIdentifier(*it));
3232bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3242bde8e466a4451c7319e3a072d118917957d6554Steve Block
3252bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::deleteAllOrigins()
3262bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3272bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_isActive);
3282bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(isMainThread());
3292bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_thread);
3302bde8e466a4451c7319e3a072d118917957d6554Steve Block
3312bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_isActive)
3322bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3332bde8e466a4451c7319e3a072d118917957d6554Steve Block
3342bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
3352bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockOrigins(m_originSetGuard);
3362bde8e466a4451c7319e3a072d118917957d6554Steve Block        willDeleteAllOrigins();
3372bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_originSet.clear();
3382bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3392bde8e466a4451c7319e3a072d118917957d6554Steve Block
3402bde8e466a4451c7319e3a072d118917957d6554Steve Block    PageGroup::clearLocalStorageForAllOrigins();
3412bde8e466a4451c7319e3a072d118917957d6554Steve Block
3422bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_thread->scheduleTask(LocalStorageTask::createDeleteAllOrigins());
3432bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3442bde8e466a4451c7319e3a072d118917957d6554Steve Block
3452bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::syncDeleteAllOrigins()
3462bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3472bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!isMainThread());
3482bde8e466a4451c7319e3a072d118917957d6554Steve Block
3492bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockDatabase(m_databaseGuard);
3502bde8e466a4451c7319e3a072d118917957d6554Steve Block
3512bde8e466a4451c7319e3a072d118917957d6554Steve Block    openTrackerDatabase(false);
3522bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_database.isOpen())
3532bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3542bde8e466a4451c7319e3a072d118917957d6554Steve Block
3552bde8e466a4451c7319e3a072d118917957d6554Steve Block    SQLiteStatement statement(m_database, "SELECT origin, path FROM Origins");
3562bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (statement.prepare() != SQLResultOk) {
3572bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Failed to prepare statement.");
3582bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3592bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3602bde8e466a4451c7319e3a072d118917957d6554Steve Block
3612bde8e466a4451c7319e3a072d118917957d6554Steve Block    int result;
3622bde8e466a4451c7319e3a072d118917957d6554Steve Block    while ((result = statement.step()) == SQLResultRow) {
3632bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!canDeleteOrigin(statement.getColumnText(0)))
3642bde8e466a4451c7319e3a072d118917957d6554Steve Block            continue;
3652bde8e466a4451c7319e3a072d118917957d6554Steve Block
3662bde8e466a4451c7319e3a072d118917957d6554Steve Block        SQLiteFileSystem::deleteDatabaseFile(statement.getColumnText(1));
3672bde8e466a4451c7319e3a072d118917957d6554Steve Block
3682bde8e466a4451c7319e3a072d118917957d6554Steve Block        {
3692bde8e466a4451c7319e3a072d118917957d6554Steve Block            MutexLocker lockClient(m_clientGuard);
3702bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (m_client)
3712bde8e466a4451c7319e3a072d118917957d6554Steve Block                m_client->dispatchDidModifyOrigin(statement.getColumnText(0));
3722bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
3732bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3742bde8e466a4451c7319e3a072d118917957d6554Steve Block
3752bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (result != SQLResultDone)
3762bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Failed to read in all origins from the database.");
3772bde8e466a4451c7319e3a072d118917957d6554Steve Block
3782bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_database.isOpen())
3792bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_database.close();
3802bde8e466a4451c7319e3a072d118917957d6554Steve Block
3812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath())) {
3822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // In the case where it is not possible to delete the database file (e.g some other program
3832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // like a virus scanner is accessing it), make sure to remove all entries.
3842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        openTrackerDatabase(false);
3852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!m_database.isOpen())
3862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
3872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins");
3882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (deleteStatement.prepare() != SQLResultOk) {
3892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            LOG_ERROR("Unable to prepare deletion of all origins");
3902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
3912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
3922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!deleteStatement.executeCommand()) {
3932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            LOG_ERROR("Unable to execute deletion of all origins");
3942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
3952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
3962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
3972bde8e466a4451c7319e3a072d118917957d6554Steve Block    SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_storageDirectoryPath);
3982bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3992bde8e466a4451c7319e3a072d118917957d6554Steve Block
4002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid StorageTracker::deleteOriginOnMainThread(void* originIdentifier)
4012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
4022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(isMainThread());
4032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
4042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    String identifier = adoptRef(reinterpret_cast<StringImpl*>(originIdentifier));
4052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    tracker().deleteOrigin(identifier);
4062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
4072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
4082bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::deleteOrigin(const String& originIdentifier)
4092bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4102bde8e466a4451c7319e3a072d118917957d6554Steve Block    deleteOrigin(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier).get());
4112bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4122bde8e466a4451c7319e3a072d118917957d6554Steve Block
4132bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::deleteOrigin(SecurityOrigin* origin)
4142bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4152bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_isActive);
4162bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(isMainThread());
4172bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(m_thread);
4182bde8e466a4451c7319e3a072d118917957d6554Steve Block
4192bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_isActive)
4202bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4212bde8e466a4451c7319e3a072d118917957d6554Steve Block
4222bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Before deleting database, we need to clear in-memory local storage data
4232bde8e466a4451c7319e3a072d118917957d6554Steve Block    // in StorageArea, and to close the StorageArea db. It's possible for an
4242bde8e466a4451c7319e3a072d118917957d6554Steve Block    // item to be added immediately after closing the db and cause StorageAreaSync
4252bde8e466a4451c7319e3a072d118917957d6554Steve Block    // to reopen the db before the db is deleted by a StorageTracker thread.
4262bde8e466a4451c7319e3a072d118917957d6554Steve Block    // In this case, reopening the db in StorageAreaSync will cancel a pending
4272bde8e466a4451c7319e3a072d118917957d6554Steve Block    // StorageTracker db deletion.
4282bde8e466a4451c7319e3a072d118917957d6554Steve Block    PageGroup::clearLocalStorageForOrigin(origin);
4292bde8e466a4451c7319e3a072d118917957d6554Steve Block
4302bde8e466a4451c7319e3a072d118917957d6554Steve Block    String originId = origin->databaseIdentifier();
4312bde8e466a4451c7319e3a072d118917957d6554Steve Block
4322bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
4332bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockOrigins(m_originSetGuard);
4342bde8e466a4451c7319e3a072d118917957d6554Steve Block        willDeleteOrigin(originId);
4352bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_originSet.remove(originId);
4362bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4372bde8e466a4451c7319e3a072d118917957d6554Steve Block
4382bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_thread->scheduleTask(LocalStorageTask::createDeleteOrigin(originId));
4392bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4402bde8e466a4451c7319e3a072d118917957d6554Steve Block
4412bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::syncDeleteOrigin(const String& originIdentifier)
4422bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4432bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!isMainThread());
4442bde8e466a4451c7319e3a072d118917957d6554Steve Block
4452bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockDatabase(m_databaseGuard);
4462bde8e466a4451c7319e3a072d118917957d6554Steve Block
4472bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!canDeleteOrigin(originIdentifier)) {
4482bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Attempted to delete origin '%s' while it was being created\n", originIdentifier.ascii().data());
4492bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4502bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4512bde8e466a4451c7319e3a072d118917957d6554Steve Block
4522bde8e466a4451c7319e3a072d118917957d6554Steve Block    openTrackerDatabase(false);
4532bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_database.isOpen())
4542bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4552bde8e466a4451c7319e3a072d118917957d6554Steve Block
4562bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Get origin's db file path, delete entry in tracker's db, then delete db file.
4572bde8e466a4451c7319e3a072d118917957d6554Steve Block    SQLiteStatement pathStatement(m_database, "SELECT path FROM Origins WHERE origin=?");
4582bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (pathStatement.prepare() != SQLResultOk) {
4592bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Unable to prepare selection of path for origin '%s'", originIdentifier.ascii().data());
4602bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4612bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4622bde8e466a4451c7319e3a072d118917957d6554Steve Block    pathStatement.bindText(1, originIdentifier);
4632bde8e466a4451c7319e3a072d118917957d6554Steve Block    int result = pathStatement.step();
4642bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (result != SQLResultRow) {
4652bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Unable to find origin '%s' in Origins table", originIdentifier.ascii().data());
4662bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4672bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4682bde8e466a4451c7319e3a072d118917957d6554Steve Block
4692bde8e466a4451c7319e3a072d118917957d6554Steve Block    String path = pathStatement.getColumnText(0);
4702bde8e466a4451c7319e3a072d118917957d6554Steve Block
4712bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!path.isEmpty());
4722bde8e466a4451c7319e3a072d118917957d6554Steve Block
4732bde8e466a4451c7319e3a072d118917957d6554Steve Block    SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins where origin=?");
4742bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (deleteStatement.prepare() != SQLResultOk) {
4752bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Unable to prepare deletion of origin '%s'", originIdentifier.ascii().data());
4762bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4772bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4782bde8e466a4451c7319e3a072d118917957d6554Steve Block    deleteStatement.bindText(1, originIdentifier);
4792bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!deleteStatement.executeCommand()) {
4802bde8e466a4451c7319e3a072d118917957d6554Steve Block        LOG_ERROR("Unable to execute deletion of origin '%s'", originIdentifier.ascii().data());
4812bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4822bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4832bde8e466a4451c7319e3a072d118917957d6554Steve Block
4842bde8e466a4451c7319e3a072d118917957d6554Steve Block    SQLiteFileSystem::deleteDatabaseFile(path);
4852bde8e466a4451c7319e3a072d118917957d6554Steve Block
4862bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool shouldDeleteTrackerFiles = false;
4872bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
4882bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker originLock(m_originSetGuard);
4892bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_originSet.remove(originIdentifier);
4902bde8e466a4451c7319e3a072d118917957d6554Steve Block        shouldDeleteTrackerFiles = m_originSet.isEmpty();
4912bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4922bde8e466a4451c7319e3a072d118917957d6554Steve Block
4932bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (shouldDeleteTrackerFiles) {
4942bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_database.close();
4952bde8e466a4451c7319e3a072d118917957d6554Steve Block        SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath());
4962bde8e466a4451c7319e3a072d118917957d6554Steve Block        SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_storageDirectoryPath);
4972bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4982bde8e466a4451c7319e3a072d118917957d6554Steve Block
4992bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
5002bde8e466a4451c7319e3a072d118917957d6554Steve Block        MutexLocker lockClient(m_clientGuard);
5012bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (m_client)
5022bde8e466a4451c7319e3a072d118917957d6554Steve Block            m_client->dispatchDidModifyOrigin(originIdentifier);
5032bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
5042bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5052bde8e466a4451c7319e3a072d118917957d6554Steve Block
5062bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::willDeleteAllOrigins()
5072bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5082bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!m_originSetGuard.tryLock());
5092bde8e466a4451c7319e3a072d118917957d6554Steve Block
5102bde8e466a4451c7319e3a072d118917957d6554Steve Block    OriginSet::const_iterator end = m_originSet.end();
5112bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (OriginSet::const_iterator it = m_originSet.begin(); it != end; ++it)
5122bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_originsBeingDeleted.add((*it).threadsafeCopy());
5132bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5142bde8e466a4451c7319e3a072d118917957d6554Steve Block
5152bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::willDeleteOrigin(const String& originIdentifier)
5162bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5172bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(isMainThread());
5182bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!m_originSetGuard.tryLock());
5192bde8e466a4451c7319e3a072d118917957d6554Steve Block
5202bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_originsBeingDeleted.add(originIdentifier);
5212bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5222bde8e466a4451c7319e3a072d118917957d6554Steve Block
5232bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool StorageTracker::canDeleteOrigin(const String& originIdentifier)
5242bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5252bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!m_databaseGuard.tryLock());
5262bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockOrigins(m_originSetGuard);
5272bde8e466a4451c7319e3a072d118917957d6554Steve Block    return m_originsBeingDeleted.contains(originIdentifier);
5282bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5292bde8e466a4451c7319e3a072d118917957d6554Steve Block
5302bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::cancelDeletingOrigin(const String& originIdentifier)
5312bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5322bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_isActive)
5332bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
5342bde8e466a4451c7319e3a072d118917957d6554Steve Block
5352bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockDatabase(m_databaseGuard);
5362bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockOrigins(m_originSetGuard);
5372bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_originsBeingDeleted.isEmpty())
5382bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_originsBeingDeleted.remove(originIdentifier);
5392bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5402bde8e466a4451c7319e3a072d118917957d6554Steve Block
5412bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::setClient(StorageTrackerClient* client)
5422bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5432bde8e466a4451c7319e3a072d118917957d6554Steve Block    MutexLocker lockClient(m_clientGuard);
5442bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_client = client;
5452bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5462bde8e466a4451c7319e3a072d118917957d6554Steve Block
5472bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::syncLocalStorage()
5482bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5492bde8e466a4451c7319e3a072d118917957d6554Steve Block    PageGroup::syncLocalStorage();
5502bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5512bde8e466a4451c7319e3a072d118917957d6554Steve Block
5522bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool StorageTracker::isActive()
5532bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5542bde8e466a4451c7319e3a072d118917957d6554Steve Block    return m_isActive;
5552bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5562bde8e466a4451c7319e3a072d118917957d6554Steve Block
5572bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid StorageTracker::setIsActive(bool flag)
5582bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5592bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_isActive = flag;
5602bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5612bde8e466a4451c7319e3a072d118917957d6554Steve Block
5622bde8e466a4451c7319e3a072d118917957d6554Steve Block} // namespace WebCore
5632bde8e466a4451c7319e3a072d118917957d6554Steve Block
5642bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif // ENABLE(DOM_STORAGE)
565