Changeset 45594 in webkit


Ignore:
Timestamp:
Jul 7, 2009 7:29:15 AM (15 years ago)
Author:
jmalonzo@webkit.org
Message:

2009-07-07 Ben Murdoch <benm@google.com>

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.
Location:
trunk
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r45593 r45594  
     12009-07-07  Ben Murdoch  <benm@google.com>
     2
     3        Reviewed by Antti Koivisto.
     4
     5        HTML5 Database becomes locked if a transaction is in progress when the page is refreshed.
     6        https://bugs.webkit.org/show_bug.cgi?id=25711
     7
     8        Tests fix for https://bugs.webkit.org/show_bug.cgi?id=25711, where
     9        web storage databases could become locked until the browser is
     10        shut down if the page is refreshed whilst a transaction is in
     11        progress.
     12
     13        * storage/database-lock-after-reload-expected.txt: Added.
     14        * storage/database-lock-after-reload.html: Added.
     15        * storage/resources/database-lock-after-reload-2.html: Added.
     16
    1172009-07-07  Simon Hausmann  <hausmann@webkit.org>
    218
  • trunk/WebCore/ChangeLog

    r45592 r45594  
     12009-07-07  Ben Murdoch  <benm@google.com>
     2
     3        Reviewed by Antti Koivisto.
     4
     5        HTML5 Database becomes locked if a transaction is in progress when the page is refreshed.
     6        https://bugs.webkit.org/show_bug.cgi?id=25711
     7
     8        Fix for https://bugs.webkit.org/show_bug.cgi?id=25711 where web
     9        storage databases could become locked until the browser is shut
     10        down if the page is refreshed whilst a transaction is in progress.
     11
     12        Test: storage/database-lock-after-reload.html
     13
     14        * storage/Database.cpp:
     15        (WebCore::Database::Database):
     16        (WebCore::Database::close): add code to inform the database thread we've closed the database.
     17        (WebCore::Database::performOpenAndVerify): add code to inform the database thread we've opened a database.
     18        * storage/Database.h:
     19        (WebCore::Database::opened): return true iff the underlying sqlite database has been opened but not closed.
     20        * storage/DatabaseThread.cpp:
     21        (WebCore::DatabaseThread::databaseThread): Before the database thread terminates, close any databases that ran transactions in this thread.
     22        (WebCore::DatabaseThread::recordDatabaseOpen): Records a database that executed a transaction in this thread.
     23        (WebCore::DatabaseThread::recordDatabaseClosed): Removes a database from the set of open databases.
     24        * storage/DatabaseThread.h:
     25        (WebCore::DatabaseThread::getThreadID): return the thread id for the database thread.
     26
    1272009-07-07  Jiahua Huang  <jhuangjiahua@gmail.com>
    228
  • trunk/WebCore/storage/Database.cpp

    r45487 r45594  
    6161namespace WebCore {
    6262
     63// If we sleep for more the 30 seconds while blocked on SQLITE_BUSY, give up.
     64static const int maxSqliteBusyWaitTime = 30000;
     65
    6366const String& Database::databaseInfoTableName()
    6467{
     
    133136    , m_deleted(false)
    134137    , m_stopped(false)
     138    , m_opened(false)
    135139{
    136140    ASSERT(document);
     
    317321void Database::close()
    318322{
    319     m_sqliteDatabase.close();
     323    if (m_opened) {
     324        ASSERT(m_document->databaseThread());
     325        ASSERT(currentThread() == document()->databaseThread()->getThreadID());
     326        m_sqliteDatabase.close();
     327        m_document->databaseThread()->recordDatabaseClosed(this);
     328        m_opened = false;
     329    }
    320330}
    321331
     
    424434    }
    425435
     436    m_opened = true;
     437    if (m_document->databaseThread())
     438        m_document->databaseThread()->recordDatabaseOpen(this);
     439
    426440    ASSERT(m_databaseAuthorizer);
    427441    m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer);
     442    m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime);
    428443
    429444    if (!m_sqliteDatabase.tableExists(databaseInfoTableName())) {
  • trunk/WebCore/storage/Database.h

    r43283 r45594  
    101101
    102102    void close();
     103    bool opened() const { return m_opened; }
    103104   
    104105    void stop();
     
    142143    bool m_stopped;
    143144
     145    bool m_opened;
     146
    144147    SQLiteDatabase m_sqliteDatabase;
    145148    RefPtr<DatabaseAuthorizer> m_databaseAuthorizer;
  • 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
  • trunk/WebCore/storage/DatabaseThread.h

    r43283 r45594  
    5757    void unscheduleDatabaseTasks(Database*);
    5858
     59    void recordDatabaseOpen(Database*);
     60    void recordDatabaseClosed(Database*);
     61    ThreadIdentifier getThreadID() { return m_threadID; }
     62
    5963private:
    6064    DatabaseThread();
     
    6872
    6973    MessageQueue<RefPtr<DatabaseTask> > m_queue;
     74
     75    // This set keeps track of the open databases that have been used on this thread.
     76    typedef HashSet<RefPtr<Database> > DatabaseSet;
     77    DatabaseSet m_openDatabaseSet;
    7078};
    7179
Note: See TracChangeset for help on using the changeset viewer.