summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/Modules/webdatabase/DatabaseThread.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/Modules/webdatabase/DatabaseThread.cpp')
-rw-r--r--Source/WebCore/Modules/webdatabase/DatabaseThread.cpp177
1 files changed, 46 insertions, 131 deletions
diff --git a/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp b/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp
index 7ee764ca0..0dde5f726 100644
--- a/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp
+++ b/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,25 +29,17 @@
#include "config.h"
#include "DatabaseThread.h"
-#if ENABLE(SQL_DATABASE)
-
#include "Database.h"
#include "DatabaseTask.h"
#include "Logging.h"
-#include "SQLTransactionClient.h"
+#include "SQLTransaction.h"
#include "SQLTransactionCoordinator.h"
#include <wtf/AutodrainedPool.h>
namespace WebCore {
DatabaseThread::DatabaseThread()
- : m_threadID(0)
-#if PLATFORM(IOS)
- , m_paused(false)
-#endif
- , m_transactionClient(adoptPtr(new SQLTransactionClient()))
- , m_transactionCoordinator(adoptPtr(new SQLTransactionCoordinator()))
- , m_cleanupSync(0)
+ : m_transactionCoordinator(std::make_unique<SQLTransactionCoordinator>())
{
m_selfRef = this;
}
@@ -66,7 +58,7 @@ DatabaseThread::~DatabaseThread()
bool DatabaseThread::start()
{
- MutexLocker lock(m_threadCreationMutex);
+ LockHolder lock(m_threadCreationMutex);
if (m_threadID)
return true;
@@ -76,13 +68,10 @@ bool DatabaseThread::start()
return m_threadID;
}
-void DatabaseThread::requestTermination(DatabaseTaskSynchronizer *cleanupSync)
+void DatabaseThread::requestTermination(DatabaseTaskSynchronizer* cleanupSync)
{
m_cleanupSync = cleanupSync;
LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this);
-#if PLATFORM(IOS)
- m_pausedQueue.kill();
-#endif
m_queue.kill();
}
@@ -104,99 +93,18 @@ void DatabaseThread::databaseThreadStart(void* vDatabaseThread)
dbThread->databaseThread();
}
-#if PLATFORM(IOS)
-class DatabaseUnpauseTask : public DatabaseTask {
-public:
- static std::unique_ptr<DatabaseUnpauseTask> create(DatabaseThread* thread)
- {
- return std::unique_ptr<DatabaseUnpauseTask>(new DatabaseUnpauseTask(thread));
- }
-
- virtual bool shouldPerformWhilePaused() const
- {
- // Since we're not locking the DatabaseThread::m_paused in the main database thread loop, it's possible that
- // a DatabaseUnpauseTask might be added to the m_pausedQueue and performed from within ::handlePausedQueue.
- // To protect against this, we allow it to be performed even if the database is paused.
- // If the thread is paused when it is being performed, the tasks from the paused queue will simply be
- // requeued instead of performed.
- return true;
- }
-
-private:
- DatabaseUnpauseTask(DatabaseThread* thread)
- : DatabaseTask(0, 0)
- , m_thread(thread)
- {}
-
- virtual void doPerformTask()
- {
- m_thread->handlePausedQueue();
- }
-#if !LOG_DISABLED
- virtual const char* debugTaskName() const { return "DatabaseUnpauseTask"; }
-#endif
-
- DatabaseThread* m_thread;
-};
-
-
-void DatabaseThread::setPaused(bool paused)
-{
- if (m_paused == paused)
- return;
-
- MutexLocker pausedLocker(m_pausedMutex);
- m_paused = paused;
- if (!m_paused)
- scheduleTask(DatabaseUnpauseTask::create(this));
-}
-
-void DatabaseThread::handlePausedQueue()
-{
- Vector<std::unique_ptr<DatabaseTask> > pausedTasks;
- while (auto task = m_pausedQueue.tryGetMessage())
- pausedTasks.append(std::move(task));
-
- for (unsigned i = 0; i < pausedTasks.size(); ++i) {
- AutodrainedPool pool;
-
- std::unique_ptr<DatabaseTask> task(pausedTasks[i].release());
- {
- MutexLocker pausedLocker(m_pausedMutex);
- if (m_paused) {
- m_pausedQueue.append(std::move(task));
- continue;
- }
- }
-
- if (terminationRequested())
- break;
-
- task->performTask();
- }
-}
-#endif //PLATFORM(IOS)
-
-
void DatabaseThread::databaseThread()
{
{
// Wait for DatabaseThread::start() to complete.
- MutexLocker lock(m_threadCreationMutex);
+ LockHolder lock(m_threadCreationMutex);
LOG(StorageAPI, "Started DatabaseThread %p", this);
}
while (auto task = m_queue.waitForMessage()) {
AutodrainedPool pool;
-#if PLATFORM(IOS)
- if (!m_paused || task->shouldPerformWhilePaused())
- task->performTask();
- else
- m_pausedQueue.append(std::move(task));
-#else
task->performTask();
-#endif
}
// Clean up the list of all pending transactions on this database thread
@@ -206,69 +114,76 @@ void DatabaseThread::databaseThread()
// 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
// inconsistent or locked state.
- if (m_openDatabaseSet.size() > 0) {
- // As the call to close will modify the original set, we must take a copy to iterate over.
- DatabaseSet openSetCopy;
- openSetCopy.swap(m_openDatabaseSet);
- DatabaseSet::iterator end = openSetCopy.end();
- for (DatabaseSet::iterator it = openSetCopy.begin(); it != end; ++it)
- (*it).get()->close();
+ DatabaseSet openSetCopy;
+ {
+ LockHolder lock(m_openDatabaseSetMutex);
+ if (m_openDatabaseSet.size() > 0) {
+ // As the call to close will modify the original set, we must take a copy to iterate over.
+ openSetCopy.swap(m_openDatabaseSet);
+ }
}
+ for (auto& openDatabase : openSetCopy)
+ openDatabase->performClose();
+
// Detach the thread so its resources are no longer of any concern to anyone else
detachThread(m_threadID);
DatabaseTaskSynchronizer* cleanupSync = m_cleanupSync;
// Clear the self refptr, possibly resulting in deletion
- m_selfRef = 0;
+ m_selfRef = nullptr;
if (cleanupSync) // Someone wanted to know when we were done cleaning up.
cleanupSync->taskCompleted();
}
-void DatabaseThread::recordDatabaseOpen(DatabaseBackend* database)
+void DatabaseThread::recordDatabaseOpen(Database& database)
{
+ LockHolder lock(m_openDatabaseSetMutex);
+
ASSERT(currentThread() == m_threadID);
- ASSERT(database);
- ASSERT(!m_openDatabaseSet.contains(database));
- m_openDatabaseSet.add(database);
+ ASSERT(!m_openDatabaseSet.contains(&database));
+ m_openDatabaseSet.add(&database);
}
-void DatabaseThread::recordDatabaseClosed(DatabaseBackend* database)
+void DatabaseThread::recordDatabaseClosed(Database& database)
{
+ LockHolder lock(m_openDatabaseSetMutex);
+
ASSERT(currentThread() == m_threadID);
- ASSERT(database);
- ASSERT(m_queue.killed() || m_openDatabaseSet.contains(database));
- m_openDatabaseSet.remove(database);
+ ASSERT(m_queue.killed() || m_openDatabaseSet.contains(&database));
+ m_openDatabaseSet.remove(&database);
}
-void DatabaseThread::scheduleTask(std::unique_ptr<DatabaseTask> task)
+void DatabaseThread::scheduleTask(std::unique_ptr<DatabaseTask>&& task)
{
ASSERT(!task->hasSynchronizer() || task->hasCheckedForTermination());
- m_queue.append(std::move(task));
+ m_queue.append(WTFMove(task));
}
-void DatabaseThread::scheduleImmediateTask(std::unique_ptr<DatabaseTask> task)
+void DatabaseThread::scheduleImmediateTask(std::unique_ptr<DatabaseTask>&& task)
{
ASSERT(!task->hasSynchronizer() || task->hasCheckedForTermination());
- m_queue.prepend(std::move(task));
+ m_queue.prepend(WTFMove(task));
}
-class SameDatabasePredicate {
-public:
- SameDatabasePredicate(const DatabaseBackend* database) : m_database(database) { }
- bool operator()(const DatabaseTask& task) const { return task.database() == m_database; }
-private:
- const DatabaseBackend* m_database;
-};
+void DatabaseThread::unscheduleDatabaseTasks(Database& database)
+{
+ // The thread loop is running, sp some tasks for this database may still be executed. This is unavoidable.
+ m_queue.removeIf([&database] (const DatabaseTask& task) {
+ return &task.database() == &database;
+ });
+}
-void DatabaseThread::unscheduleDatabaseTasks(DatabaseBackend* database)
+bool DatabaseThread::hasPendingDatabaseActivity() const
{
- // Note that the thread loop is running, so some tasks for the database
- // may still be executed. This is unavoidable.
- SameDatabasePredicate predicate(database);
- m_queue.removeIf(predicate);
+ LockHolder lock(m_openDatabaseSetMutex);
+ for (auto& database : m_openDatabaseSet) {
+ if (database->hasPendingCreationEvent() || database->hasPendingTransaction())
+ return true;
+ }
+ return false;
}
+
} // namespace WebCore
-#endif