DatabaseThread.cpp [plain text]
#include "config.h"
#include "DatabaseThread.h"
#include "AutodrainedPool.h"
#include "Database.h"
#include "DatabaseTask.h"
#include "Logging.h"
namespace WebCore {
DatabaseThread::DatabaseThread()
: m_threadID(0)
{
m_selfRef = this;
}
DatabaseThread::~DatabaseThread()
{
}
bool DatabaseThread::start()
{
MutexLocker lock(m_threadCreationMutex);
if (m_threadID)
return true;
m_threadID = createThread(DatabaseThread::databaseThreadStart, this, "WebCore::Database");
return m_threadID;
}
void DatabaseThread::requestTermination()
{
LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this);
m_queue.kill();
}
bool DatabaseThread::terminationRequested() const
{
return m_queue.killed();
}
void* DatabaseThread::databaseThreadStart(void* vDatabaseThread)
{
DatabaseThread* dbThread = static_cast<DatabaseThread*>(vDatabaseThread);
return dbThread->databaseThread();
}
void* DatabaseThread::databaseThread()
{
{
MutexLocker lock(m_threadCreationMutex);
LOG(StorageAPI, "Started DatabaseThread %p", this);
}
AutodrainedPool pool;
while (true) {
RefPtr<DatabaseTask> task;
if (!m_queue.waitForMessage(task))
break;
task->performTask();
pool.cycle();
}
LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());
detachThread(m_threadID);
m_selfRef = 0;
return 0;
}
void DatabaseThread::scheduleTask(PassRefPtr<DatabaseTask> task)
{
m_queue.append(task);
}
void DatabaseThread::scheduleImmediateTask(PassRefPtr<DatabaseTask> task)
{
m_queue.prepend(task);
}
void DatabaseThread::unscheduleDatabaseTasks(Database* database)
{
Deque<RefPtr<DatabaseTask> > filteredReverseQueue;
RefPtr<DatabaseTask> task;
while (m_queue.tryGetMessage(task)) {
if (task->database() != database)
filteredReverseQueue.append(task);
}
while (!filteredReverseQueue.isEmpty()) {
m_queue.append(filteredReverseQueue.first());
filteredReverseQueue.removeFirst();
}
}
}