Commit 7b9f7cc5 authored by tkent@chromium.org's avatar tkent@chromium.org

Tentative fix of a crash in Oilpan GC after a database thread termination.

Make sure DatabaseThread::m_openDatabaseSet has no backing store
when a database thread is terminated.
m_openDatabaseSet outlives a database thread, and its backing store
is allocated in the database thread.  So, we should unlink the
backing store before the thread termination.

* DatabaseThread::cleanupDatabaseThread
 It's possible m_openDatabaseSet.size() is zero and
 m_openDatabaseSet still has backing store in the following scenario:
  1. A web page opens a database.  m_openDatabaseSet has it.
  2. Chromium calls DatabaseTracker::closeDatabasesImmediately()
  3. It calls m_openDatabaseSet.remove().

* DatabaseThread::recordDatabaseOpen
  Don't add a Database object after termination request.
  I think this can't happen. But we change it just in case.

This CL has no tests. It's very hard to make an automated test for the
scenario.

BUG=423271

Review URL: https://codereview.chromium.org/657023003

git-svn-id: svn://svn.chromium.org/blink/trunk@183730 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent f8a9e418
...@@ -114,6 +114,7 @@ void DatabaseThread::cleanupDatabaseThread() ...@@ -114,6 +114,7 @@ void DatabaseThread::cleanupDatabaseThread()
for (HeapHashSet<Member<Database> >::iterator it = openSetCopy.begin(); it != end; ++it) for (HeapHashSet<Member<Database> >::iterator it = openSetCopy.begin(); it != end; ++it)
(*it)->close(); (*it)->close();
} }
m_openDatabaseSet.clear();
m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThreadCompleted, this))); m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThreadCompleted, this)));
} }
...@@ -130,7 +131,9 @@ void DatabaseThread::recordDatabaseOpen(Database* database) ...@@ -130,7 +131,9 @@ void DatabaseThread::recordDatabaseOpen(Database* database)
ASSERT(isDatabaseThread()); ASSERT(isDatabaseThread());
ASSERT(database); ASSERT(database);
ASSERT(!m_openDatabaseSet.contains(database)); ASSERT(!m_openDatabaseSet.contains(database));
m_openDatabaseSet.add(database); MutexLocker lock(m_terminationRequestedMutex);
if (!m_terminationRequested)
m_openDatabaseSet.add(database);
} }
void DatabaseThread::recordDatabaseClosed(Database* database) void DatabaseThread::recordDatabaseClosed(Database* database)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment