Ignore:
Timestamp:
Jul 7, 2009, 7:29:15 AM (16 years ago)
Author:
[email protected]
Message:

2009-07-07 Ben Murdoch <[email protected]>

Reviewed by Antti Koivisto.

HTML5 Database becomes locked if a transaction is in progress when the page is refreshed.
https://bugs.webkit.org/show_bug.cgi?id=25711

Tests fix for https://bugs.webkit.org/show_bug.cgi?id=25711, where
web storage databases could become locked until the browser is
shut down if the page is refreshed whilst a transaction is in
progress.

  • storage/database-lock-after-reload-expected.txt: Added.
  • storage/database-lock-after-reload.html: Added.
  • storage/resources/database-lock-after-reload-2.html: Added.

Fix for https://bugs.webkit.org/show_bug.cgi?id=25711 where web
storage databases could become locked until the browser is shut
down if the page is refreshed whilst a transaction is in progress.

Test: storage/database-lock-after-reload.html

  • storage/Database.cpp: (WebCore::Database::Database): (WebCore::Database::close): add code to inform the database thread we've closed the database. (WebCore::Database::performOpenAndVerify): add code to inform the database thread we've opened a database.
  • storage/Database.h: (WebCore::Database::opened): return true iff the underlying sqlite database has been opened but not closed.
  • storage/DatabaseThread.cpp: (WebCore::DatabaseThread::databaseThread): Before the database thread terminates, close any databases that ran transactions in this thread. (WebCore::DatabaseThread::recordDatabaseOpen): Records a database that executed a transaction in this thread. (WebCore::DatabaseThread::recordDatabaseClosed): Removes a database from the set of open databases.
  • storage/DatabaseThread.h: (WebCore::DatabaseThread::getThreadID): return the thread id for the database thread.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/storage/DatabaseThread.cpp

    r43663 r45594  
    100100    LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());
    101101
     102    // Close the databases that we ran transactions on. This ensures that if any transactions are still open, they are rolled back and we don't leave the database in an
     103    // inconsistent or locked state.
     104    if (m_openDatabaseSet.size() > 0) {
     105        // As the call to close will modify the original set, we must take a copy to iterate over.
     106        DatabaseSet openSetCopy;
     107        openSetCopy.swap(m_openDatabaseSet);
     108        DatabaseSet::iterator end = openSetCopy.end();
     109        for (DatabaseSet::iterator it = openSetCopy.begin(); it != end; ++it)
     110           (*it)->close();
     111    }
     112
    102113    // Detach the thread so its resources are no longer of any concern to anyone else
    103114    detachThread(m_threadID);
     
    107118
    108119    return 0;
     120}
     121
     122void DatabaseThread::recordDatabaseOpen(Database* database)
     123{
     124    ASSERT(currentThread() == m_threadID);
     125    ASSERT(database);
     126    ASSERT(!m_openDatabaseSet.contains(database));
     127    m_openDatabaseSet.add(database);
     128}
     129
     130void DatabaseThread::recordDatabaseClosed(Database* database)
     131{
     132    ASSERT(currentThread() == m_threadID);
     133    ASSERT(database);
     134    ASSERT(m_queue.killed() || m_openDatabaseSet.contains(database));
     135    m_openDatabaseSet.remove(database);
    109136}
    110137
Note: See TracChangeset for help on using the changeset viewer.