15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webdatabase/DatabaseTracker.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h"
351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContextTask.h"
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "modules/webdatabase/Database.h"
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "modules/webdatabase/DatabaseClient.h"
38bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "modules/webdatabase/DatabaseContext.h"
39521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "modules/webdatabase/QuotaTracker.h"
4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "modules/webdatabase/sqlite/SQLiteFileSystem.h"
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/DatabaseIdentifier.h"
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SecurityOrigin.h"
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SecurityOriginHash.h"
4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/Platform.h"
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebDatabaseObserver.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Assertions.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/StdLibExtras.h"
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic void databaseClosed(Database* database)
5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
53e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (Platform::current()->databaseObserver()) {
54e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Platform::current()->databaseObserver()->databaseClosed(
5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            createDatabaseIdentifierFromSecurityOrigin(database->securityOrigin()),
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            database->stringIdentifier());
5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DatabaseTracker& DatabaseTracker::tracker()
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    AtomicallyInitializedStatic(DatabaseTracker&, tracker = *new DatabaseTracker());
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return tracker;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)DatabaseTracker::DatabaseTracker()
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SQLiteFileSystem::registerSQLiteVFS();
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
71bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)bool DatabaseTracker::canEstablishDatabase(DatabaseContext* databaseContext, const String& name, const String& displayName, unsigned long estimatedSize, DatabaseError& error)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ExecutionContext* executionContext = databaseContext->executionContext();
7451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool success = DatabaseClient::from(executionContext)->allowDatabase(executionContext, name, displayName, estimatedSize);
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!success)
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        error = DatabaseError::GenericSecurityError;
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return success;
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String& name, bool)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
82e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    return createDatabaseIdentifierFromSecurityOrigin(origin) + "/" + name + "#";
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DatabaseTracker::addOpenDatabase(Database* database)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_openDatabaseMap)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_openDatabaseMap = adoptPtr(new DatabaseOriginMap);
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
91e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    String originIdentifier = createDatabaseIdentifierFromSecurityOrigin(database->securityOrigin());
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DatabaseNameMap* nameMap = m_openDatabaseMap->get(originIdentifier);
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!nameMap) {
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nameMap = new DatabaseNameMap();
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_openDatabaseMap->set(originIdentifier, nameMap);
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String name(database->stringIdentifier());
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DatabaseSet* databaseSet = nameMap->get(name);
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!databaseSet) {
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        databaseSet = new DatabaseSet();
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nameMap->set(name, databaseSet);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    databaseSet->add(database);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class NotifyDatabaseObserverOnCloseTask FINAL : public ExecutionContextTask {
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
1107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static PassOwnPtr<NotifyDatabaseObserverOnCloseTask> create(PassRefPtrWillBeRawPtr<Database> database)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return adoptPtr(new NotifyDatabaseObserverOnCloseTask(database));
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void performTask(ExecutionContext*) OVERRIDE
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
11751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        databaseClosed(m_database.get());
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual bool isCleanupTask() const OVERRIDE
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    explicit NotifyDatabaseObserverOnCloseTask(PassRefPtrWillBeRawPtr<Database> database)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_database(database)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RefPtrWillBeCrossThreadPersistent<Database> m_database;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DatabaseTracker::removeOpenDatabase(Database* database)
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
136e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    String originIdentifier = createDatabaseIdentifierFromSecurityOrigin(database->securityOrigin());
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_openDatabaseMap);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DatabaseNameMap* nameMap = m_openDatabaseMap->get(originIdentifier);
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!nameMap)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String name(database->stringIdentifier());
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DatabaseSet* databaseSet = nameMap->get(name);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!databaseSet)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DatabaseSet::iterator found = databaseSet->find(database);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (found == databaseSet->end())
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    databaseSet->remove(found);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (databaseSet->isEmpty()) {
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nameMap->remove(name);
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        delete databaseSet;
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nameMap->isEmpty()) {
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_openDatabaseMap->remove(originIdentifier);
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            delete nameMap;
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ExecutionContext* executionContext = database->databaseContext()->executionContext();
1631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!executionContext->isContextThread())
1641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        executionContext->postTask(NotifyDatabaseObserverOnCloseTask::create(database));
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else
16651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        databaseClosed(database);
167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DatabaseTracker::prepareToOpenDatabase(Database* database)
170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(database->databaseContext()->executionContext()->isContextThread());
172e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (Platform::current()->databaseObserver()) {
173e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Platform::current()->databaseObserver()->databaseOpened(
17451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            createDatabaseIdentifierFromSecurityOrigin(database->securityOrigin()),
17551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            database->stringIdentifier(),
17651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            database->displayName(),
17751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            database->estimatedSize());
17851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DatabaseTracker::failedToOpenDatabase(Database* database)
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ExecutionContext* executionContext = database->databaseContext()->executionContext();
1841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!executionContext->isContextThread())
1851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        executionContext->postTask(NotifyDatabaseObserverOnCloseTask::create(database));
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
18751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        databaseClosed(database);
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciunsigned long long DatabaseTracker::getMaxSizeForDatabase(const Database* database)
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned long long spaceAvailable = 0;
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned long long databaseSize = 0;
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    QuotaTracker::instance().getDatabaseSizeAndSpaceAvailableToOrigin(
195e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        createDatabaseIdentifierFromSecurityOrigin(database->securityOrigin()),
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        database->stringIdentifier(), &databaseSize, &spaceAvailable);
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return databaseSize + spaceAvailable;
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class DatabaseTracker::CloseOneDatabaseImmediatelyTask FINAL : public ExecutionContextTask {
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static PassOwnPtr<CloseOneDatabaseImmediatelyTask> create(const String& originIdentifier, const String& name, Database* database)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return adoptPtr(new CloseOneDatabaseImmediatelyTask(originIdentifier, name, database));
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void performTask(ExecutionContext*) OVERRIDE
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DatabaseTracker::tracker().closeOneDatabaseImmediately(m_originIdentifier, m_name, m_database);
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
2137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CloseOneDatabaseImmediatelyTask(const String& originIdentifier, const String& name, Database* database)
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_originIdentifier(originIdentifier.isolatedCopy())
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_name(name.isolatedCopy())
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_database(database)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String m_originIdentifier;
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String m_name;
2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Database* m_database; // Intentionally a raw pointer.
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void DatabaseTracker::closeDatabasesImmediately(const String& originIdentifier, const String& name)
226521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_openDatabaseMap)
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DatabaseNameMap* nameMap = m_openDatabaseMap->get(originIdentifier);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!nameMap)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DatabaseSet* databaseSet = nameMap->get(name);
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!databaseSet)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We have to call closeImmediately() on the context thread and we cannot safely add a reference to
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the database in our collection when not on the context thread (which is always the case given
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // current usage).
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (DatabaseSet::iterator it = databaseSet->begin(); it != databaseSet->end(); ++it)
2431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        (*it)->databaseContext()->executionContext()->postTask(CloseOneDatabaseImmediatelyTask::create(originIdentifier, name, *it));
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DatabaseTracker::closeOneDatabaseImmediately(const String& originIdentifier, const String& name, Database* database)
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // First we have to confirm the 'database' is still in our collection.
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_openDatabaseMap)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DatabaseNameMap* nameMap = m_openDatabaseMap->get(originIdentifier);
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!nameMap)
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DatabaseSet* databaseSet = nameMap->get(name);
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!databaseSet)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DatabaseSet::iterator found = databaseSet->find(database);
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (found == databaseSet->end())
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // And we have to call closeImmediately() without our collection lock being held.
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    database->closeImmediately();
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
271e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} // namespace blink
272